POJ 3468(树状数组的威力)
之前说过这是线段树的裸题,但是当看了http://kenby.iteye.com/blog/962159 这篇题解后我简直震惊了,竟然能如此巧妙地转化为用树状数组来处理,附上部分截图(最好还是进入原网址细细品味):
依照他的思路附上我的代码:
1 #include<cstdio> 2 #include<cstring> 3 #define lowbit(x) ((x)&-(x)) 4 typedef long long LL; 5 const int maxn= 100003; 6 LL org[maxn+3]; 7 8 struct tree{ 9 LL c[maxn+3]; 10 void clear() { memset(c,0,sizeof(c)); } 11 LL sum(int x) const { 12 LL res= 0; 13 while(x){ 14 res+= c[x]; 15 x-= lowbit(x); 16 } 17 return res; 18 } 19 void add(int x, LL d){ 20 while(x<=maxn){ 21 c[x]+= d; 22 x+= lowbit(x); 23 } 24 } 25 } d1,d2; 26 27 inline LL sum(int x) { 28 return org[x]+(x+1)*d1.sum(x)-d2.sum(x); 29 } 30 31 int main(){ 32 int n,q,a,b; 33 LL x,c; 34 while(~scanf("%d%d",&n,&q)){ 35 memset(org,0,sizeof(org)); 36 d1.clear(); 37 d2.clear(); 38 for(int i=1; i<=n; ++i){ 39 scanf("%lld",&x); 40 org[i]= org[i-1]+x; 41 } 42 while(q--){ 43 getchar(); 44 if(getchar()=='Q'){ 45 scanf("%d%d",&a,&b); 46 printf("%lld\n",sum(b)-sum(a-1)); 47 } 48 else { 49 scanf("%d%d%lld",&a,&b,&c); 50 d1.add(a,c); 51 d1.add(b+1,-c); 52 d2.add(a,c*a); 53 d2.add(b+1,-c*(b+1)); 54 } 55 } 56 } 57 return 0; 58 }
提交后发现比线段树要快一点,再加上代码的精简性,树状数组,果然够强大!