线段树1

来源:互联网 发布:软件项目测试总结 编辑:程序博客网 时间:2024/06/05 03:41
#include<cstring>#include<iostream>#define M 50005#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1 //10+01/*left,right,root,middle*/int sum[M<<2];inline void PushPlus(int rt){sum[rt] = sum[rt<<1] + sum[rt<<1|1];}void Build(int l, int r, int rt) //第一个节点的区间在[l...r]{if(l == r){scanf("%d", &sum[rt]);return ;}int m = ( l + r )>>1;Build(lson);Build(rson);PushPlus(rt);}void Updata(int p, int add, int l, int r, int rt)  //从rt开始找 找到p节点更新  单点更新{if( l == r ){sum[rt] += add;   //若修改为 sum[rt]=add  则变成了单点替换return ;}int m = ( l + r ) >> 1;if(p <= m)Updata(p, add, lson);elseUpdata(p, add, rson);PushPlus(rt);}int Query(int L,int R,int l,int r,int rt) //查询区间[L,R]求和[L...R]   节点1是[l...r]  {if( L <= l && r <= R ){return sum[rt];}int m = ( l + r ) >> 1;int ans=0;if(L<=m )ans+=Query(L,R,lson);if(R>m)ans+=Query(L,R,rson);return ans;}//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 = max(ret , query(L , R , lson));  //    if (R > m) ret = max(ret , query(L , R , rson));  //    return ret;  //} int main(){int T, n, a, b;scanf("%d",&T);for( int i = 1; i <= T; ++i ){printf("Case %d:\n",i);scanf("%d",&n);Build(1,n,1);char op[10];while( scanf("%s",op) &&op[0]!='E' ){scanf("%d %d", &a, &b);if(op[0] == 'Q')printf("%d\n",Query(a,b,1,n,1));else if(op[0] == 'S')Updata(a,-b,1,n,1);elseUpdata(a,b,1,n,1);}}return 0;}

0 0