ACM常用模板——数据结构——树状数组

(一)
一维BIT求和
模型:求区间[l,r]的和
  1. #define maxn 10005
  2. using namespace std;
  3. int n,bit[maxn];
  4. int sum(int i)//前i项的和
  5. {
  6. int s=0;
  7. while(i>0)s+=bit[i],i-=i&-i;
  8. return s;
  9. }
  10. void add(int i,int x)//第i项增加x,更新bit数组
  11. {
  12. while(i<=n){bit[i]+=x;i+=i&-i;}
  13. }
  14. int main()
  15. {
  16. int i,x,s,e,m;
  17. while(~scanf("%d%d",&n,&m)){
  18. memset(bit,0,sizeof(bit));
  19. for(i=1;i<=n;i++){
  20. scanf("%d",&x);
  21. add(i,x);
  22. }
  23. while(m--){
  24. scanf("%d%d",&s,&e);
  25. printf("%d\n",sum(e)-sum(s-1));
  26. }
  27. }
  28. }

(二)树状数组求逆序数
  1. #define maxn 10005
  2. using namespace std;
  3. int n,bit[maxn],a[maxn];
  4. int sum(int i)//前i项的和
  5. {
  6. int s=0;
  7. while(i>0)s+=bit[i],i-=i&-i;
  8. return s;
  9. }
  10. void add(int i,int x)//第i项增加x,更新bit数组
  11. {
  12. while(i<=n){bit[i]+=x;i+=i&-i;}
  13. }
  14. int solve()//求逆序数个数
  15. {
  16. int ans=0,i;
  17. for(i=0;i<n;i++){
  18. ans+=i-sum(a[i]);
  19. add(a[i],1);
  20. }
  21. return ans;
  22. }
  23. int main()
  24. {
  25. int i;
  26. while(~scanf("%d",&n)){
  27. memset(bit,0,sizeof(bit));
  28. for(i=0;i<n;i++){
  29. scanf("%d",&a[i]);
  30. }
  31. printf("%d\n",solve());
  32. }
  33. }
(三)二维树状数组
模型:矩阵初始化为0,C x1 y1 x2 y2:把矩阵翻转(0变1,,1变0),Q x y:查询位置x y的值
  1. const int MAXN = 1010;
  2. int c[MAXN][MAXN];
  3. int n;
  4. int sum(int x,int y)
  5. {
  6. int ret = 0;
  7. for(int i = x;i > 0;i -= i&(-i))
  8. for(int j = y;j > 0;j -= j&(-j))
  9. ret += c[i][j];
  10. return ret;
  11. }
  12. void add(int x,int y,int val)
  13. {
  14. for(int i = x;i <= n;i += i&(-i))
  15. for(int j = y;j <= n;j += j&(-j))
  16. c[i][j] += val;
  17. }
  18. int main()
  19. {
  20. int T;
  21. scanf("%d",&T);
  22. while(T--)
  23. {
  24. int q;
  25. scanf("%d%d",&n,&q);
  26. memset(c,0,sizeof(c));
  27. char op[10];
  28. int x1,y1,x2,y2;
  29. while(q--)
  30. {
  31. scanf("%s",op);
  32. if(op[0] == 'C')
  33. {
  34. scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
  35. add(x1,y1,1);
  36. add(x2+1,y1,1);
  37. add(x1,y2+1,1);
  38. add(x2+1,y2+1,1);
  39. }
  40. else
  41. {
  42. scanf("%d%d",&x1,&y1);
  43. if(sum(x1,y1)%2 == 0)printf("0\n");
  44. else printf("1\n");
  45. }
  46. }
  47. if(T > 0)printf("\n");
  48. }
  49. return 0;
  50. }
阅读更多
文章标签: acm 算法 数据结构
个人分类: acm
想对作者说点什么? 我来说一句

线段树 树状数组 数据结构

2011年07月24日 1.29MB 下载

ACM常用模板 ACM常用模板

2010年07月04日 79KB 下载

ACM 算法 常用模板

2010年07月28日 280B 下载

线段树和树状数组入门介绍

2010年08月11日 155KB 下载

ACM之java速成

2013年12月13日 52KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭