数状数组

来源:互联网 发布:阿里云服务器ip段 编辑:程序博客网 时间:2024/05/17 02:59

数状数组

数状数组求解:

下图是数状数组C和原数组a

数状形数组的规律:

C1=a1
C2=a1+a2
C3=a3
C4=a1+a2+a3+a4
C5=a5
……
C8=a1+a2+a3+a4+a5+a6+a7+a8
……
C2n=a1+a2+….+a2^n
本质:对于序列a,数组C中的第x个元素为
 
C[x] = a[x – 2k+ 1] + … + a[x]
 
 
 Ki的二进制表示中末尾0的个数
    
1) 与x对应的2k的计算 int lowbit ( int x ){return x & (-x); } 
2) a[k]增加d时,数组C中相应元素的修改 void change(int k,int d,int n)//n是数组的最大下标{while (k<=n){c[k]=c[k]+d;k=k+lowbit(k);}}
 
3)计算a[1]+a[2]+……+a[K]int getsum(int k){int t=0;while (k>0){t=t+c[k];k=k-lowbit(k);}return t;}

 
完整代码:
#include <iostream>using namespace std;#define N 100int a[N],c[N];int lowbit(int x){return x & (-x); }void change(int k,int d,int n){while (k<=n){c[k]=c[k]+d; k=k+lowbit(k); } }int getsum(int k){int t=0;while (k>0){t=t+c[k];k=k-lowbit(k);}return t;} int main( ){         int i,n=8;          memset(c,0,sizeof(c));for (i=1; i<=n; i++){  a[i]=i;change(i,i,n);}for (i=1; i<=n; i++)cout<<a[i]<<" "<<c[i]<<" "<<getsum(i)<<endl;a[3]=a[3]+50;          change(3,50,8);for (i=1; i<=n; i++)cout<<a[i]<<" "<<c[i]<<" "<<getsum(i)<<endl;return 0;}

 
 
 
 
原创粉丝点击