树状数组模板 Tree Array
---恢复内容开始---
这几天去浙江省选当垫底(Orz我是蒟蒻),然后顺便复习下树状数组
关于树状数组,其实很好理解,主要就是lowbit()操作的巧妙
树状数组是一种非常优雅的数据结构.当要频繁的对数组元素进行修改,同时又要频繁的查询数组内任一区间元素之和的时候,可以考虑使用树状数组.
换句话说,树状数组最基本的应用:
对于一个数组,如果有多次操作,每次的操作有两种:1、修改数组中某一元素的值,2、求和,求数组元素a[1]+a[2]+…a[num]的和。——Km的小天地
其实树状数组自己写几个代码就很容易理解了,也可以参见这里(Km的小天地)
1 // Tree-Array 模板 2 #include<bits/stdc++.h> 3 using namespace std; 4 const int MAX=100000; 5 int a[MAX+10],c[MAX+10],n,s[MAX+10]; 6 int lowbit(int x) {return x&(-x);} 7 // 修改:修改第x个元素,把第x个元素改为x+delta 8 // O(logn) 9 // 支持单点修改,区间更新复杂度O(nlogn) 10 void modify(int x,int delta) { 11 while(x<=n) { 12 c[x]+=delta; 13 x+=lowbit(x); 14 } 15 } 16 // 查询:查询[1,x]区间和,若要查询[x,y],则需调用[1,y]-[1,x] 17 // O(logn) 18 int cal(int x) { 19 int ret=0; 20 while(x!=0) { 21 ret+=c[x]; 22 x-=lowbit(x); 23 } 24 return ret; 25 } 26 27 int main() { 28 scanf("%d",&n); 29 for (int i=1;i<=n;++i) { 30 scanf("%d",&a[i]); 31 sum[i]=sum[i-1]+a[i]; 32 c[i]=sum[i]-sum[i-lowbit(i)]; 33 } 34 int T; 35 scanf("%d",&T); 36 while(T--) { 37 //在线修改查询 38 //这里的代码自行填写 39 } 40 return 0; 41 }
树状数组的应用
HDU 1166 敌兵布阵
纯模板题目,很简单。这里要说一点,我的代码在main部分可能缩进会有点乱,因为HDU经常为多组数据,我是先写好TreeArray再进行添加多数据测试。
1 # include <iostream> 2 # include <stdio.h> 3 # include <string.h> 4 using namespace std; 5 int a[50010], c[50010], n, sum[50010]={}; 6 int lowbit(int x) {return x&(-x);} 7 void mdf(int p, int del) { 8 while(p<=n) { 9 c[p]+=del; 10 p+=lowbit(p); 11 } 12 } 13 int ca(int dg) { 14 int r=0; 15 while(dg!=0) { 16 r+=c[dg]; 17 dg-=lowbit(dg); 18 } 19 return r; 20 } 21 int main() {int T,ft; 22 scanf("%d", &T);ft=T; 23 while(T--) { 24 printf("Case %d:\n",ft-T); 25 scanf("%d", &n); 26 for (int i=1;i<=n;++i) { 27 scanf("%d", &a[i]); 28 sum[i]=sum[i-1]+a[i]; 29 c[i]=sum[i]-sum[i-lowbit(i)]; 30 } 31 //for (int i=1;i<=n;++i) printf("%d ", c[i]); 32 while(1) { 33 char st[10]; int ta,tb; 34 scanf("%s", st); 35 //printf("%s %d %d",st,ta,tb); 36 if (strcmp(st,"End")==0) break; 37 scanf("%d %d",&ta,&tb); 38 if (strcmp(st,"Add")==0) { 39 mdf(ta,tb); 40 } 41 else if (strcmp(st,"Sub")==0) { 42 mdf(ta,-1*tb); 43 } 44 else if (strcmp(st,"Query")==0) { 45 if(ta>tb) {int p=ta;ta=tb;tb=p;} 46 printf("%d\n",ca(tb)-ca(ta-1)); 47 } 48 }} 49 return 0; 50 }
好吧我暂时就写到这一题树状数组,果然我还是太弱了ORZ各位神犇们
---恢复内容结束---
这篇文章由TonyFang发布。
所有解释权归TonyFang所有。
Mailto: tony-fang@map-le.net