C - A Simple Problem with Integers - poj 3468(区间更新)

题意:有一个比较长的区间可能是100000.长度, 每个点都有一个值(值还比较大),现在有一些操作,C abc, 把区间a-b内全部加上c, Qab,求区间ab的值。

分析:很明显我们不可能对区间的每个点都进行更新,不过我们可以使用一个op的开关,如果op等于0说明这个不需要更新,如果等于1就说明需要进行更新,这样只需要和插入的时候进行一下更新即可
***********************************************************************
注意:在向下更新的时候如果是更新子树有可能一个区间会更新多次,而子树区间更新的时候不能乘本区间的更新值,只能乘根节点的更新值,根节点的跟新值用完后归0;
 
#include<stdio.h>
#include<math.h>
#include< string.h>
#include<algorithm>
using  namespace std;

#define maxn 100005
#define Lson root<<1,L,tree[root].Mid()
#define Rson root<<1|1,tree[root].Mid()+1,R

struct Tree // op等于0的时候子树不需要更新,op等于1需要更新
{
     int L, R, op; // 需要向下更新的值为e
     long  long sum, e; // 因为区间和比较大,所以使用long long 保存
     int Mid(){ return (L+R)/ 2;}
     int Len(){ return (R-L+ 1);}
}tree[maxn* 4];
long  long val[maxn];

void Down( int root) // 向下更新
{
     if(tree[root].op && tree[root].L != tree[root].R)
    {
        tree[root].op =  false;
        tree[root<< 1].op = tree[root<< 1| 1].op =  true;
        tree[root<< 1].e += tree[root].e;
        tree[root<< 1| 1].e += tree[root].e;

        tree[root<< 1].sum += tree[root<< 1].Len() * tree[root].e;
        tree[root<< 1| 1].sum += tree[root<< 1| 1].Len() * tree[root].e;

        tree[root].e =  0;
    }
}
void Build( int root,  int L,  int R)
{
    tree[root].L = L, tree[root].R = R;
    tree[root].op =  false;

     if(L == R)
    {
        tree[root].sum = val[L];
         return ;
    }

    Build(Lson);
    Build(Rson);

    tree[root].sum = tree[root<< 1].sum + tree[root<< 1| 1].sum;
}
void Insert( int root,  int L,  int R,  long  long e)
{
    Down(root);

    tree[root].sum += (R-L+ 1) * e;

     if(tree[root].L == L && tree[root].R == R)
    {
        tree[root].e = e, tree[root].op =  true;
         return ;
    }

     if(R <= tree[root].Mid())
        Insert(root<< 1, L, R, e);
     else  if(L > tree[root].Mid())
        Insert(root<< 1| 1, L, R, e);
     else
    {
        Insert(Lson, e);
        Insert(Rson, e);
    }
}
long  long Query( int root,  int L,  int R)
{
    Down(root);

     if(tree[root].L == L && tree[root].R == R)
         return tree[root].sum;
     if(R <= tree[root].Mid())
         return Query(root<< 1, L, R);
     else  if(L > tree[root].Mid())
         return Query(root<< 1| 1, L, R);
     else
         return Query(Lson) + Query(Rson);
}

int main()
{
     int i, N, Q;

     while(scanf( " %d%d ", &N, &Q) != EOF)
    {
         for(i= 1; i<=N; i++)
            scanf( " %I64d ", &val[i]);
        Build( 11, N);

         int a, b;  char s[ 10];
         long  long c;

         while(Q--)
        {
            scanf( " %s%d%d ", s, &a, &b);

             if(s[ 0] ==  ' C ')
            {
                scanf( " %I64d ", &c);
                Insert( 1, a, b, c);
            }
             else
            {
                 long  long ans = Query( 1, a, b);
                printf( " %I64d\n ", ans);
            }
        }
    }

     return  0;
}

/*
5 2
1 2 3 4 5
C 1 5 5
Q 1 1
*/

你可能感兴趣的:(Integer)