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 }
View Code

  提交后发现比线段树要快一点,再加上代码的精简性,树状数组,果然够强大!

posted @ 2015-01-01 16:20  Newdawn_ALM  阅读(218)  评论(0编辑  收藏  举报