NYOJ 116 树状数组

来源:互联网 发布:腾讯云怎么绑定域名 编辑:程序博客网 时间:2024/04/28 12:35

初学树状数组。。

 

 

这是线段树的图,由图可知,c[1]=a[1];c2=a[1]+a[2];c[3]=a[3];c[4]=a[1]+a[2]+a[3]+a[4];c[5]=a[5];

c[6]=a[5]+a[6];c[7]=a[7];c[8]=a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8];

可以得到这个规律,i为奇数时,c[i]=a[i],这里1,3,5,7便是例子。偶数时这里就跟2的幂有关系了,i的因子中最多有2的多少次幂,例如4,2的2次幂,为4,所以从a[4]数共4个数的值,即a[1],a[2],a[3],a[4],当i=6时,因子数最大为2,所以数2个数,即a[5],a[6],同理i=8时,2的三次幂,等于8,即a[1]+.....a[8]的值.网上查询可知,公式为

c[n]=a(n-a^k+1)+......+a[n]; (其中k为从右往走数0的个数,也即第一个出现1的位置,起点从0开始)

这里可以用一个函数计算得

int lowbit(int x)

{

return x&(-x);

}

这个函数怎样理解呢?

x=1时,x的二进制表示为(假设位数为8) 0000 0001

     -x的二进制表示为           1111 1111

                        --->  0000 0001 =1;

x=6时  x的二进制表示为           0000 0110

     -x的二进制表示为           1111 1010

                        --->  0000 0010 =2;

这里相信你明白了,若不懂负数的二进制表示,可百度查之

这个函数的目的就是求出2^k (k为往右数第一个出现1的位置起点从0开始或者0出现的个数,见上)

接下来就是求和了,

int Sum(int n)

{

   int sum=0;

   while(n>0)

{

    sum+=c[n];

    n=n-lowbit(n);

}

return sum;

}

这里具体该怎样理解呢?我们可以看成求一段路径的和,不同于普通的一维数组按照下标为1一次递增或递减,这里是按照树的结构,每次logn,即求路径(x,x-lowit(x),....1)为下标的和

最后修改某个结点的值

void change(int i,int x)

{

  while(i<=m)           //m个结点的总和

  {

      c[i]=c[i]+x;

      i=i+lowbit(i);

  }

}

如果上面求和理解了,这步应该很快理解了,改变了某个结点的值,那么对应的路径上相应的点也要改变,结束的条件即为到达根结点。

下面来看看这道题

链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=116

1,若采取常规的方法,求解,时间的复杂度为O(n^2);

2,采取树状数组的方法,AC代码:

#include<iostream>#include<stdio.h>#include<cstring>using namespace std;int c[1000008],m,Q,t;int lowbit(int x){ return x&(-x);}int Sum(int n){ int sum=0; while(n>0) {  sum=sum+c[n];  n=n-lowbit(n); } return sum;}void change(int i,int x){ while(i<=m) {  c[i]=c[i]+x;  i=i+lowbit(i); }} int main(){ scanf("%d%d",&m,&Q); char key[10]; int start,end; for(int i=1;i<=m;++i) {   scanf("%d",&t);   change(i,t); }    while(Q--)    {  scanf("%s%d%d",key,&start,&end);     if(key[0]=='Q')     printf("%d\n",Sum(end)-Sum(start-1));     else if(key[0]=='A')     change(start,end); } return 0;}

参考资料来源:http://www.cnblogs.com/zhangshu/archive/2011/08/16/2141396.html

                            http://hi.baidu.com/czyuan_acm/item/b14bff6ab6ffd093c5d249db

原创粉丝点击