HDU-1166-敌兵布阵(树状数组,附解释)

来源:互联网 发布:java汽车租赁系统代码 编辑:程序博客网 时间:2024/05/28 23:20

HDU-1166-敌兵布阵(树状数组)

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


初学树状数组,,  
题目大意:更新点查区间,,
简单介绍一下树状数组,看下图。


c1 = a1

c3 = a3

c4 = a1 + a2 + a3 + a4

c5 = a5

c6 = a5 + a6

c7 = a7

c8 = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8

c9=a9
c10=a9+a10


对于序列a,我们设一个数组C定义C[i] = a[i – 2^k + 1] + … + a[i],k为i在二进制下末尾0的个数

求2^k

求x在二进制下末尾0的个数(第一个一出现的位置)

int lowbit(int x)  {      return x&(x^(x-1));  }  
将a[p]的值加上一个值x

void update(int p,int x){while(p<=n){c[p]+=x;p+=lowbit(p);}}
求前p项和

int sum(int p)   {      int sum=0;      while(p>0)      {          sum+=c[p];          p-=lowbit(p);      }      return sum;  }   
题目代码:

#include<cstdio>#include<cstring>#define lowbit(x) (x&(x^(x-1)))#define maxn 50010using namespace std;int c[maxn];int n;void update(int p,int x)///给 a[p] 加上 x{    while(p<=n){        c[p]+=x;        p+=lowbit(p);    }}int sum(int p) ///求前P项的和{    int sum=0;    while(p>0){        sum+=c[p];        p-=lowbit(p);    }    return sum;}int main(){    int T,t=0;    char str[10];    scanf("%d",&T);    while(T--)    {        int x,y;        scanf("%d",&n);        memset(c,0,sizeof(c));        for(int i=1;i<=n;i++){            scanf("%d",&x);            update(i,x);        }        printf("Case %d:\n",++t);        while(scanf("%s",str)&&str[0]!='E'){            scanf("%d %d",&x,&y);            if(str[0]=='A')                update(x,y);            else if(str[0]=='S')                update(x,-y);            else if(str[0]=='Q'){                printf("%d\n",sum(y)-sum(x-1));            }        }    }    return 0;}

参考文章:http://blog.csdn.net/cambridgeacm/article/details/7771782


原创粉丝点击