poj 3468A Simple Problem with Integers经典线段树

这个可以作为线段树的模板来使用了,很经典,以前总是搞不清楚要向下更新,这次是明白了,多次修改很多区间时没必要每次都去修改,可以最后一块修改

View Code
  1 #include<stdio.h>
  2 #include<string.h>
  3 #define N 100005
  4 struct node
  5 {
  6     int r,l;
  7     long long sum,v;
  8 };
  9 node p[4*N];
 10 long long val[N];
 11 void build(int l,int r,int i)
 12 {
 13     p[i].r=r;
 14     p[i].l=l;
 15     p[i].v=p[i].sum=0;
 16     if(r==l)
 17     {
 18         //p[i].v=val[i];
 19         p[i].sum=val[l];
 20         return;
 21     }
 22     int mid=(l+r)>>1;
 23     build(l,mid,i<<1);
 24     build(mid+1,r,i<<1|1);
 25     p[i].sum=p[i<<1].sum+p[i<<1|1].sum;
 26 }
 27 void update(int l,int r,int v,int i)
 28 {
 29     if(p[i].r==r&&p[i].l==l)
 30     {
 31         p[i].sum+=(v*(r-l+1));
 32         p[i].v+=v;
 33         return;
 34     }
 35     if(p[i].v)
 36     {
 37         p[i<<1].v+=p[i].v;
 38         p[i<<1|1].v+=p[i].v;
 39         p[i<<1].sum+=(p[i].v*(p[i<<1].r-p[i<<1].l+1));
 40         p[i<<1|1].sum+=(p[i].v*(p[i<<1|1].r-p[i<<1|1].l+1));
 41         p[i].v=0;
 42     }
 43     int mid=(p[i].r+p[i].l)>>1;
 44     if(r<=mid)
 45     update(l,r,v,i<<1);
 46     else if(mid<l)
 47     update(l,r,v,i<<1|1);
 48     else
 49     {
 50         update(l,mid,v,i<<1);
 51         update(mid+1,r,v,i<<1|1);
 52     }
 53     p[i].sum=p[i<<1].sum+p[i<<1|1].sum;
 54     //printf("%d %d\n",i,p[i].sum);
 55 }
 56 long long query(int l,int r,int i)
 57 {
 58     if(p[i].l==l&&p[i].r==r)
 59     return p[i].sum;
 60     if(p[i].v)
 61     {
 62         p[i<<1].v+=p[i].v;
 63         p[i<<1|1].v+=p[i].v;
 64         p[i<<1].sum+=(p[i].v*(p[i<<1].r-p[i<<1].l+1));
 65         p[i<<1|1].sum+=(p[i].v*(p[i<<1|1].r-p[i<<1|1].l+1));
 66         p[i].v=0;
 67     }
 68     int mid=(p[i].l+p[i].r)>>1;
 69     if(r<=mid)
 70     return query(l,r,i<<1);
 71     else if(mid<l)
 72     return query(l,r,i<<1|1);
 73     return query(l,mid,i<<1)+query(mid+1,r,i<<1|1);
 74 }
 75 int main()
 76 {
 77     int n,i,m;
 78     int a,b;
 79     long long c;
 80     char ch[2];
 81     while(~scanf("%d%d",&n,&m))
 82     {
 83         for(i=1;i<=n;i++)
 84         scanf("%lld",&val[i]);
 85         build(1,n,1);
 86         //printf("%d\n",p[1].sum);
 87         while(m--)
 88         {
 89             scanf("%s%d%d",ch,&a,&b);
 90             if(ch[0]=='C')
 91             {
 92                 scanf("%lld",&c);
 93                 update(a,b,c,1);
 94             }
 95             else
 96             {
 97                 printf("%lld\n",query(a,b,1));
 98             }
 99         }
100     }
101     return 0;
102 }
原文地址:https://www.cnblogs.com/caozhenhai/p/2527112.html