hdu 1166 敌兵布阵

来源:互联网 发布:福建师大网络教育专业 编辑:程序博客网 时间:2024/06/03 15:12

题目链接  hdu 1166 敌兵布阵

线段树单点更新 求区间的和

//单点更新#include<iostream>#include<cstdio>#include<cstdlib>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 55555using namespace std;int sum[maxn<<2];void pushup(int rt) //向上更新{    sum[rt]=sum[rt<<1]+sum[rt<<1|1];//rt<<1为左儿子节点,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);  //从[l,m]建树    build(rson);//从[m+1,r]建树    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 sum =0 ; //初始化    if(L<=m) sum+=query(L,R,lson); //若一部分区间在中点的左边,继续递归询问    if(R>m) sum+=query(L,R,rson);//若一部分在中点的右边,继续递归询问    return sum;}void update(int id,int c,int op,int l,int r,int rt) //单点更新{    if(l==r)//找到叶子节点    {        if(op==1) sum[rt]+=c; //加上c        else sum[rt]-=c; //减去c        return ;    }    int m = (l+r)>>1; //找到中间节点    if(id<=m) update(id,c,op,lson); //若所要更新的节点在区间的左边 ,继续在左边找    else update(id,c,op,rson); //否则在右边查找    pushup(rt);}int main(){    int t,n,h=0;    scanf("%d",&t);    while(t--)    {        char s[10];        scanf("%d",&n);        build(1,n,1); //建树        scanf("%s",s);        printf("Case %d:\n",++h);        while(s[0]!='E')        {            int a,b;            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,1,n,1);                 else if(s[0]=='S') update(a,b,0,1,n,1);            scanf("%s",s);        }    }    return 0;}



0 0