POJ 3468 A Simple Problem with Integers(线段树)

题目链接:http://poj.org/problem?id=3468

题意:一个数列,两种操作:

(1)Q L R 询问区间[L,R]的数字之和;

(2)C L R D将区间[L,R]之间的数字同时加D。

思路:每个节点保存一个sum值和一个det值,需要注意的地方:

(1)查询或修改的区间不是当前值整个区间时,将det值下调;

(2)下调det时和修改完时修改sum值。

 #include <iostream>

 #include <cstdio>

 #include <cstring>

 using namespace std;

 

 struct Node

 {

     int L,R,mid;

     __int64 sum,det;

 };

 

 const int MAX=100005;

 Node a[MAX<<2];

 int n,m;

 __int64 b[MAX],sum[MAX];

 

 void build(int t,int L,int R)

 {

     a[t].L=L;

     a[t].R=R;

     a[t].mid=(L+R)>>1;

     a[t].sum=0;

     a[t].det=0;

     if(L==R) return;

     build(t*2,L,a[t].mid);

     build(t*2+1,a[t].mid+1,R);

 }

 

 void update(int t,int L,int R,int det)

 {

     if(a[t].L==L&&a[t].R==R)

     {

         a[t].det+=det;

         return;

     }

     if(a[t].det)

     {

         a[t*2].det+=a[t].det;

         a[t*2+1].det+=a[t].det;

         a[t].det=0;

     }

     if(R<=a[t].mid) update(t*2,L,R,det);

     else if(L>a[t].mid) update(t*2+1,L,R,det);

     else

     {

         update(t*2,L,a[t].mid,det);

         update(t*2+1,a[t].mid+1,R,det);

     }

     a[t].sum=a[t*2].sum+a[t*2+1].sum+

               a[t*2].det*(a[t].mid-a[t].L+1)+

               a[t*2+1].det*(a[t].R-a[t].mid);

 }

 

 __int64 query(int t,int L,int R)

 {

     if(a[t].L==L&&a[t].R==R)

     {

         return a[t].sum+a[t].det*(R-L+1);

     }

     if(a[t].det)

     {

         a[t].sum+=a[t].det*(a[t].R-a[t].L+1);

         a[t*2].det+=a[t].det;

         a[t*2+1].det+=a[t].det;

         a[t].det=0;

     }

     __int64 ans;

     if(R<=a[t].mid) ans=query(t*2,L,R);

     else if(L>a[t].mid) ans=query(t*2+1,L,R);

     else

     {

         ans=query(t*2,L,a[t].mid);

         ans+=query(t*2+1,a[t].mid+1,R);

     }

     return ans;

 }

 

 int main()

 {

     while(scanf("%d%d",&n,&m)!=-1)

     {

         int i;

         sum[0]=0;

         for(i=1;i<=n;i++)

         {

             scanf("%I64d",&sum[i]);

             sum[i]+=sum[i-1];

         }

         build(1,1,n);

         char cmd[5];

         int x,y,z;

         while(m--)

         {

             scanf("%s",cmd);

             if(cmd[0]=='Q')

             {

                 scanf("%d%d",&x,&y);

                 printf("%I64d\n",query(1,x,y)+sum[y]-sum[x-1]);

             }

             else

             {

                 scanf("%d%d%d",&x,&y,&z);

                 update(1,x,y,z);

             }

         }

     }

     return 0;

 }

  

 

 

你可能感兴趣的:(Integer)