概述
hdu 1166 敌兵布阵(基本操作)
有三种操作:询问区间总和,增加某个兵营的兵的数目,减少某个兵营的兵的数目。实际上也只有两个。
在更新的时候,每到一个区间就把当前区间的sum增加对应的数目,到达叶子结点是返回。这样就可以不会回溯去更新父亲结点的值。查询的时候,如果区间完全匹配,直接返回区间的sum值,否则向下寻找,直到完全匹配,然后返回它们的和就可以。这时候,结果里保存的边界是它们真正的边界。
/*更新了代码风格后*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=50005;
struct node
{
int lft,rht;
int sum;
int mid(){return MID(lft,rht);}
};
int y[N],n;
struct Segtree
{
node tree[N*4];
void build(int lft,int rht,int ind)
{
tree[ind].lft=lft; tree[ind].rht=rht;
tree[ind].sum=0;
if(lft==rht) tree[ind].sum=y[lft];
else
{
int mid=tree[ind].mid();
build(lft,mid,LL(ind));
build(mid+1,rht,RR(ind));
tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;
}
}
void updata(int pos,int ind,int valu)
{
if(tree[ind].lft==tree[ind].rht) tree[ind].sum+=valu;
else
{
int mid=tree[ind].mid();
if(pos<=mid) updata(pos,LL(ind),valu);
else updata(pos,RR(ind),valu);
tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;
}
}
int query(int st,int ed,int ind)
{
int lft=tree[ind].lft,rht=tree[ind].rht;
if(st<=lft&&rht<=ed) return tree[ind].sum;
else
{
int mid=tree[ind].mid();
int sum1=0,sum2=0;
if(st<=mid) sum1=query(st,ed,LL(ind));
if(ed>mid) sum2=query(st,ed,RR(ind));
return sum1+sum2;
}
}
}seg;
int main()
{
int t,t_cnt=0;
scanf("%d",&t);
while(t--)
{
int a,b;
char str[10];
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&y[i]);
seg.build(1,n,1);
printf("Case %d:n",++t_cnt);
while(1)
{
scanf("%s",str);
if(strcmp(str,"End")==0) break;
scanf("%d%d",&a,&b);
if(strcmp(str,"Add")==0) seg.updata(a,1,b);
else if(strcmp(str,"Sub")==0) seg.updata(a,1,-b);
else printf("%dn",seg.query(a,b,1));
}
}
return 0;
}
/*代码风格更新前*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=1000005;
int a[N];
struct node
{
int left,right,sum;
int mid(){ return left+(right-left)/2;}
};
struct Segtree
{
node tree[N*4];
void build(int left,int right,int p)
{
tree[p].left=left;
tree[p].right=right;
tree[p].sum=0;
if(left<right)
{
int mid=tree[p].mid();
build(left,mid,p*2);
build(mid+1,right,p*2+1);
}
else if(left==right)
{
tree[p].sum=a[left];
return;
}
tree[p].sum=tree[p*2].sum+tree[p*2+1].sum;
}
void updata(int pos,int p,int data)
{
tree[p].sum+=data;
int mid=tree[p].mid();
if(tree[p].left==pos&&tree[p].right==pos) return;
else if(pos<=mid) updata(pos,p*2,data);
else if(pos>mid) updata(pos,p*2+1,data);
}
int query(int be,int end,int p)
{
int left=tree[p].left;
int right=tree[p].right;
if(be<=left&&right<=end)
{
return tree[p].sum;
}
else
{
int sum1=0,sum2=0;
int mid=tree[p].mid();
if(be<=mid) sum1=query(be,end,p*2);
if(end>mid) sum2=query(be,end,p*2+1);
return sum1+sum2;
}
}
}seg;
int main()
{
int t,t_cnt=0;
scanf("%d",&t);
while(t--)
{
int n,x,y;
char temp[10];
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
printf("Case %d:n",++t_cnt);
seg.build(1,n,1);
while(scanf("%s",temp)!=EOF)
{
if(strcmp(temp,"End")==0) break;
else if(strcmp(temp,"Add")==0)
{
scanf("%d%d",&x,&y);
seg.updata(x,1,y);
}
else if(strcmp(temp,"Sub")==0)
{
scanf("%d%d",&x,&y);
seg.updata(x,1,-y);
}
else if(strcmp(temp,"Query")==0)
{
scanf("%d%d",&x,&y);
printf("%dn",seg.query(x,y,1));
}
}
}
return 0;
}
最后
以上就是阳光小蝴蝶为你收集整理的hdu 1166 敌兵布阵(单点更新)的全部内容,希望文章能够帮你解决hdu 1166 敌兵布阵(单点更新)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复