hdu1166敌兵布阵(线段树---单点更新,区间求值)

来源:互联网 发布:mac os怎么安装7208 编辑:程序博客网 时间:2024/05/29 15:21

1.题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1166

 

2.胡浩大神的模板啊!详见:

http://www.notonlysuccess.com/index.php/segment-tree-complete/

 

3.参考代码:

 

#include <cstdio>#define lson l,m,rt<<1   ///左孩子#define rson m+1,r,rt<<1|1   ///右孩子const int maxn=55555;   ///题目给的最大区间int sum[maxn<<2];   ///节点数开最大区间的4倍int PushUP(int rt){   ///把当前节点的信息更新到父节点return sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){   ///建立线段树if(l==r)  ///若是叶子节点{scanf("%d",&sum[rt]);return ;}int m=(l+r)>>1;   ///中间值build(lson);build(rson);PushUP(rt);}void update(int p,int add,int l,int r,int rt){   ///单点增减if(l==r){sum[rt]+=add;return ;}int m=(l+r)>>1;if(p<=m)update(p,add,lson);elseupdate(p,add,rson);PushUP(rt);}int query(int L,int R,int l,int r,int rt){   ///区间求和if(L<=l && r<=R)return sum[rt];int m=(l+r)>>1;int ret=0;if(L<=m)ret+=query(L,R,lson);if(R>m)ret+=query(L,R,rson);return ret;}int main(){int cas,T,n,a,b;char s[10];scanf("%d",&T);for(cas=1;cas<=T;cas++){printf("Case %d:\n",cas);scanf("%d",&n);build(1,n,1);while(scanf("%s",s)){if(s[0]=='E')break;scanf("%d %d",&a,&b);if(s[0]=='Q')printf("%d\n",query(a,b,1,n,1));else if(s[0]=='A')update(a,b,1,n,1);else if(s[0]=='S')update(a,-b,1,n,1);}}return 0;}