数状数组


数状数组求解:

下图是数状数组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]
 
 
 K i的二进制表示中末尾0的个数
      
[cpp]  view plain  copy
  1. 1) 与x对应的2k的计算  
  2.    
  3. int lowbit ( int x )  
  4. {return x & (-x); }   

[cpp]  view plain  copy
  1. 2) a[k]增加d时,数组C中相应元素的修改  
  2.   //单点更新 
  3. void change(int k,int d,int n)  
  4. //n是数组的最大下标  
  5. {while (k<=n)  
  6. {c[k]=c[k]+d;  
  7. k=k+lowbit(k);}  
  8. }  
 //区间更新 多次单点更新
[cpp]  view plain  copy
  1. 3)计算a[1]+a[2]+……+a[K]  
  2. int getsum(int k)  
  3. {int t=0;  
  4. while (k>0)  
  5. {t=t+c[k];  
  6. k=k-lowbit(k);  
  7. }  
  8. return t;  
  9. }  

 
完整代码:
[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3. #define N 100  
  4. int a[N],c[N];  
  5. int lowbit(int x)  
  6. {return x & (-x); }  
  7. void change(int k,int d,int n)  
  8. {while (k<=n)  
  9. {c[k]=c[k]+d; k=k+lowbit(k); }   
  10. }  
  11. int getsum(int k)  
  12. {int t=0;  
  13. while (k>0)  
  14. {t=t+c[k];k=k-lowbit(k);}  
  15. return t;  
  16. }  
  17.    
  18. int main( )  
  19. {         int i,n=8;  
  20.           memset(c,0,sizeof(c));  
  21. for (i=1; i<=n; i++)  
  22. {  a[i]=i;change(i,i,n);}for (i=1; i<=n; i++)  
  23. cout<<a[i]<<" "<<c[i]<<" "<<getsum(i)<<endl;  
  24. a[3]=a[3]+50;  
  25.           change(3,50,8);  
  26. for (i=1; i<=n; i++)  
  27. cout<<a[i]<<" "<<c[i]<<" "<<getsum(i)<<endl;  
  28. return 0;  
  29. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值