hdu 1166 敌兵布阵(线段树 - 单点修改 区间和查询)

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

hdu 1166 敌兵布阵(线段树 - 单点修改 区间和查询)_第1张图片

#include
#define LNode x<<1
#define RNode x<<1|1
using namespace std;

const int Max_n=5e4+10;
int sum[4*Max_n],a[Max_n];

void build(int l,int r,int x){//构建线段树(自顶向下)
    if(l==r){ sum[x]=a[l]; return ; }
    int mid=l+(r-l)/2;
    build(l,mid,LNode);
    build(mid+1,r,RNode);
    sum[x]=sum[LNode]+sum[RNode];
    //build(1,n,1);//从根开始向上建立线段树
}
//线段树查询(自顶向下)
int query(int A,int B,int l,int r,int x){///区间查询和(log(n)))
    if(A<=l&&B>=r) return sum[x];
    int mid=l+(r-l)/2,ans=0;
    if(A<=mid) ans+=query(A,B,l,mid,LNode);//查询左子树
    if(B>mid) ans+=query(A,B,mid+1,r,RNode);//查询右子树
    return ans;
}
//pos位置改为v,[l,r]:当前结点对应的区间,x:当前结点
void change(int pos,int v,int l,int r,int x){///单点修改数据(log(n))
    if(l==r) {sum[x]+=v; return ;}
    int mid=l+(r-l)/2;
    if(pos<=mid) change(pos,v,l,mid,LNode);
    else change(pos,v,mid+1,r,RNode);
    sum[x]=sum[LNode]+sum[RNode];
}

int main(){
    int T,Case=0;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        build(1,n,1);
        char b[10];
        printf("Case %d:\n",++Case);
        while(~scanf("%s",b)&&strcmp(b,"End")){
            int pos,val;
            scanf("%d%d",&pos,&val);
            if(b[0]=='Q'){
                int l=pos,r=val;
                printf("%d\n",query(l,r,1,n,1));
            }else if(b[0]=='A'){
                change(pos,val,1,n,1);
            }else if(b[0]=='S'){
                change(pos,-val,1,n,1);
            }else break;
        }
    }
    return 0;
}

你可能感兴趣的:(线段树,/,树状数组)