HDU 1166 树状数组(点更新)

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

还是敌兵布阵那一题,不过这次是用的树状数组解决的。

树状数组是一个特殊的数据结构,如图。(图片来自:百度百科)


它的作用是:1,完成单点更新。2,能快速求1-x的区间的和。

注意,数组里面没有存放每一个点的值,存放的只是上层节点的值(红色),当然存放上层节点的值,只是为了能快速的求出区间1-x的和。

#include<cstdio>
#include<cstring>
using namespace std ;
int n ;
const int maxn = 50005 ;
int lowbit(int x){  ///显示每一个节点管辖的范围的大小
    return x&(-x) ; ///返回值就是管辖范围,自己可以计算验证一下。
}
void update(int x,int *c,int d){  ///从数组最底层更新至根节点
    for(int i=x;i<=n;i+=lowbit(i)){
        c[i]+=d ;
    }
}
int summary(int x,int *c){ ///求和,求的和是从1到x的和
    int sum=0 ;
    for(int i=x;i>0;i-=lowbit(i)){
        sum+=c[i] ;
    }
    return sum ;
}
int main(){
    int T ;
    scanf("%d",&T);
    int cas=1;
    while(T--){
       scanf("%d",&n);
       int arry[maxn] ;  ///这个数组没有存放每一个点的值,而是节点的值。
       memset(arry,0,sizeof(arry));
       for(int i=0;i<n;i++){
            int a ;
            scanf("%d",&a);
            update(i+1,arry,a);
       }
       printf("Case %d:\n",cas++);
       while(true){
            char str[10] ;
            scanf("%s",str);
            if(str[0]=='E')break ;
            else if(str[0]=='A'){
                int a,b ;
                scanf("%d%d",&a,&b);
                update(a,arry,b);
            }else if(str[0]=='S'){
                int a,b ;
                scanf("%d%d",&a,&b);
                update(a,arry,-b);
            }else{
                int a,b ;
                scanf("%d%d",&a,&b);
                printf("%d\n",summary(b,arry)-summary(a-1,arry));
            }
       }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值