题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166

题目大意:给出n个点,每个点有一个值,现在有三种操作,

1.在i点加上j

2.在i点减去j

3.查询i,j区间总和

这其实是一道非常裸的线段树,但是我还是卡了好久,结果最后发现竟然是自己的freopen和代码习惯惹的祸。这道题我用了两种方法,一种是比较常规的版本,一种是不用结构体的静态树

首先来看一个常规的代码(带结构体)

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<stack>
#define maxn 500005
#define lson pos<<1
#define rson pos<<1|1
using namespace std; struct node{
int l,r,sum;
}e[maxn]; int n,a[maxn],t; void build(int l,int r,int pos)
{
e[pos].l=l;e[pos].r=r;
if(l==r)e[pos].sum=a[l];
else{
int mid=(l+r)>>;
build(l,mid,lson);build(mid+,r,rson);
e[pos].sum=e[lson].sum+e[rson].sum;//pushup操作
}
} void add(int k,int x,int pos)
{
int l=e[pos].l,r=e[pos].r;
e[pos].sum+=x;
int mid=(l+r)>>;
if(l==r&&l==k)
{
return;
}else{
if(k<=mid)add(k,x,lson);
else add(k,x,rson);
}
} void sub(int k,int x,int pos)
{
e[pos].sum-=x;
int l=e[pos].l;int r=e[pos].r;
int mid=(l+r)>>;
if(l==r&&l==k)
{
return;
}else{
if(k<=mid)sub(k,x,lson);
else sub(k,x,rson);
}
} int summ;
void query(int l,int r,int pos)
{
if(e[pos].l>=l&&e[pos].r<=r){
summ+=e[pos].sum;
}
else{
int mid=(e[pos].l+e[pos].r)/;
if(mid>=r){
query(l,r,lson);
}
else{
if(l>mid)query(l,r,rson);
else{
query(l,r,lson);query(l,r,rson);
}
}
}
} char ch[];
int main()
{
scanf("%d",&t);int y=;
while(t--)
{
y++;
printf("Case %d:\n",y);
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
scanf("\n");
build(,n,); while()
{ scanf("%s",ch);
if(ch[]=='E')break;
if(ch[]=='A'){
int x,y;
scanf("%d%d",&x,&y);
add(x,y,);
}
if(ch[]=='S')
{
int x,y;
scanf("%d%d",&x,&y);
sub(x,y,);
}
if(ch[]=='Q')
{ summ=;
int x,y;
scanf("%d%d",&x,&y);
query(x,y,);
printf("%d\n",summ);
} } }
}

打完这个代码其实不难发现,每一个pos(节点)的左右区间其实是固定的,而且还可以推出来,画个图分析一下

红色数字为pos,黑色为l,r,可以发现其实pos对应的l,r不会变,就是一棵静态树,

所以我们就可以不用结构体,只用看一个sum数组就可以解决了

来看一看代码

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define lson pos<<1
#define rson pos<<1|1
#define maxn 500005
using namespace std; int sum[maxn<<];
int a[maxn],n,m,t;
char ch[]; void pushup(int pos)
{
sum[pos]=sum[lson]+sum[rson];
} void build(int l,int r,int pos)
{
if(l==r){sum[pos]=a[l];return;}
int mid=(l+r)/;
build(l,mid,lson);
build(mid+,r,rson);
pushup(pos);
} void add(int k,int x,int pos,int l,int r)
{
if(l==r){sum[pos]+=x;return;}
int mid=(l+r)>>;
if(k<=mid)add(k,x,lson,l,mid);
else add(k,x,rson,mid+,r);
pushup(pos);
} void sub(int k,int x,int pos,int l,int r)
{
if(l==r){sum[pos]-=x;return;}
int mid=(l+r)>>;
if(k<=mid)sub(k,x,lson,l,mid);
else sub(k,x,rson,mid+,r);
pushup(pos);
} int query(int al,int ar,int l,int r,int pos)
{
if(al<=l&&r<=ar)return sum[pos];
int mid=(l+r)>>,s=;
if(al<=mid)s+=query(al,ar,l,mid,lson);
if(ar>mid) s+=query(al,ar,mid+,r,rson);
return s;
} int main()
{
scanf("%d",&t);int y=;
while(t--)
{
cout<<"Case "<<++y<<":"<<endl;
memset(sum,,sizeof(sum));
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
build(,n,);
while()
{
scanf("%s",ch);
int x,y;
if(ch[]=='E')break;
if(ch[]=='A'){
scanf("%d%d",&x,&y);
add(x,y,,,n);
}
if(ch[]=='S')
{
scanf("%d%d",&x,&y);
sub(x,y,,,n);
}
if(ch[]=='Q')
{
scanf("%d%d",&x,&y);
printf("%d\n",query(x,y,,n,));
}
}
}
}

PS:诸位OIer打代码特别是函数时要注意声明的左右点和pos的位置关系,要一一对应,不然就像我一样会调试一天

[HDU]1166敌兵布阵<静态线段树>的更多相关文章

  1. hdu 1166敌兵布阵(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    M ...

  2. hdu 1166 敌兵布阵 (线段树单点更新)

    敌兵布阵                                                         Time Limit: 2000/1000 MS (Java/Others)  ...

  3. HDU 1166 敌兵布阵(线段树/树状数组模板题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  4. HDU 1166——敌兵布阵——————【线段树单点增减、区间求和】

    敌兵布阵 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status  ...

  5. HDU 1166 敌兵布阵 【线段树-点修改--计算区间和】

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. hdu 1166 敌兵布阵(线段树区间求和)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  7. HDU 1166 敌兵布阵(线段树模板题)

    题目链接: 传送门 敌兵布阵 Time Limit: 2000MS     Memory Limit: 32768 K Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头 ...

  8. hdu 1166 敌兵布阵【线段树】(求给定区间和)

    题目链接:https://vjudge.net/contest/182746#problem/B       敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)   ...

  9. HDU 1166 敌兵布阵 (线段树模版题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. 利用canvas绘画二级树形结构图

    上周需要做一个把页面左侧列表内容拖拽到右侧区域,并且绘制成关系树的功能.看了设计图,第一反应是用canvas绘制关系线.吭哧吭哧搞定这个功能后,发现用canvas绘图,有一个很严重的缺陷.那就是如果左 ...

  2. React-Hooks 学习概览

     React-Hooks的函数 组件方式代替原来的类继承,简化代码风格,好处是大大的: 1.useState  用来声明状态变量.要从三方面掌握:声明.读取.使用.(注意:useStae是不能进行条件 ...

  3. linux yum安装MySQL5.6

    1.新开的云服务器,需要检测系统是否自带安装mysql # yum list installed | grep mysql 2.如果发现有系统自带mysql,果断这么干 # yum -y remove ...

  4. 关于js拖放功能的实现

    这是具体的拖放代码的HTML,里面依赖两个组件:EventUtil.js是兼容浏览器添加方法的库,EventTarget.js是一个发布-订阅者模式的对象库. EventUtil.js: var Ev ...

  5. XCTF---easyjava的WriteUp

    一.题目来源     题目来源:XCTF题库安卓区easyjava     题目下载链接:下载地址 二.解题过程     1.将该apk安装进夜神模拟器中,发现有一个输入框和一个按钮,随便输入信息,点 ...

  6. AlphaGo、人工智能、深度学习解读以及应用

    经过比拼,AlphaGo最终还是胜出,创造了人机大战历史上的一个新的里程碑.几乎所有的人都在谈论这件事情,这使得把“人工智能”.“深度学习”的热潮推向了新的一个高潮.AlphaGo就像科幻电影里具有人 ...

  7. Python模块二

    os模块是与操作系统交互的一个接口​ <em>#和文件夹相关 os.makedirs('dirname1/dirname2')    可生成多层递归目录 os.removedirs('di ...

  8. Core + Vue 后台管理基础框架4——前端授权

    1.前言 上篇,我们讲了后端的授权.与后端不同,前端主要是通过功能入口如菜单.按钮的显隐来控制授权的.具体来讲,就是根据指定用户的制定权限来加载对应侧边栏菜单和页面内的功能按钮.我们一个个来讲. 2. ...

  9. MySQL第三章知识第一部分

    SQL的特点:是一个综合的.功能极强并且简洁容易学的语言. SQL的功能:数据查询.数据操纵.数据定义.数据控制. 数据库系统的主要功能是通过数据库支持的数据语言来实现. 菲关系模型(层次模型.网状模 ...

  10. Java多线程并发04——合理使用线程池

    在此之前,我们已经了解了关于线程的基本知识,今天将为各位带来,线程池这一技术.关注我的公众号「Java面典」了解更多 Java 相关知识点. 为什么使用线程池?线程池做的工作主要是控制运行的线程的数量 ...