C - A Simple Problem with Integers POJ 3468(线段树+延迟标记)


C - A Simple Problem with Integers
Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I64u
Submit Status Practice POJ 3468

Description

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C abc" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q ab" means querying the sum of Aa, Aa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9

15

//线段树 的区间更新,用好延迟标记

//#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=500011;
const int inf=999999999;
#define lson (rt<<1),L,M
#define rson (rt<<1|1),M+1,R
#define M ((L+R)>>1)
#define For(i,n) for(int i=0;i<(n);i++)
template<class T>inline T read(T&x)
{
    char c;
    while((c=getchar())<=32);
    bool ok=false;
    if(c=='-')ok=true,c=getchar();
    for(x=0; c>32; c=getchar())
        x=x*10+c-'0';
    if(ok)x=-x;
    return x;
}
template<class T> inline void read_(T&x,T&y)
{
    read(x);
    read(y);
}
template<class T> inline void write(T x)
{
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x+'0');
    else write(x/10),putchar(x%10+'0');
}
template<class T>inline void writeln(T x)
{
    write(x);
    putchar('\n');
}
//-------IO template------
typedef __int64 LL;
struct node
{
    LL sum;
    LL inv;
    node(){sum=0;inv=0;}
}p[maxn<<2];

void build(LL rt,LL L,LL R)
{
    if(L==R)
    {
        scanf("%I64d",&p[rt].sum);//read(p[rt].sum);
        return;
    }
    build(lson);
    build(rson);
    p[rt].sum=p[rt<<1].sum+p[rt<<1|1].sum;
}

void update(LL rt,LL L,LL R,LL x,LL y,LL add)
{
    if(L==x&&R==y)
    {
        p[rt].inv+=add;
        p[rt].sum+=(LL)add*(R-L+1);
        return;
    }
    if(p[rt].inv)///p[rt].inv可能收负数,之前写成了p[rt].inv>0 导致WA很多次
    {
        p[rt<<1].inv+=p[rt].inv;
        p[rt<<1|1].inv+=p[rt].inv;
        p[rt<<1].sum+=(LL)p[rt].inv*(M-L+1);
        p[rt<<1|1].sum+=(LL)p[rt].inv*(R-M);
        p[rt].inv=0;
    }
    if(y<=M)
        update(lson,x,y,add);
    else if(x>M)
        update(rson,x,y,add);
    else{
        update(lson,x,M,add);
        update(rson,M+1,y,add);
    }
    p[rt].sum=p[rt<<1].sum+p[rt<<1|1].sum;
}

LL query(LL rt,LL L,LL R,LL x,LL y)
{
    if(x==L&&y==R)
    {
        return p[rt].sum;//+p[rt].inv*(R-L+1);
    }
     if(p[rt].inv)
     {
        p[rt<<1].inv+=p[rt].inv;
        p[rt<<1|1].inv+=p[rt].inv;
        p[rt<<1].sum+=(LL)p[rt].inv*(M-L+1);
        p[rt<<1|1].sum+=(LL)p[rt].inv*(R-M);
        p[rt].inv=0;
     }
    if(y<=M)
        return query(lson,x,y);
    else if(x>M)
        return query(rson,x,y);
    else return query(lson,x,M)+query(rson,M+1,y);
}

int main()
{
    //#ifndef ONLINE_JUDGE
   // freopen("in.txt","r",stdin);
   // #endif // ONLINE_JUDGE
    LL m,n,i,j,k,t;
    while(~scanf("%I64d%I64d",&n,&m))
    {
        build(1,1,n);
        char op[2];
        while(m--)
        {
            LL  x,y;
            scanf("%s",op);scanf("%I64d%I64d",&x,&y);
            if(op[0]=='Q')
            {
                printf("%I64d\n",query(1,1,n,x,y));
            }
            else{
                LL z;
                scanf("%I64d",&z);
                update(1,1,n,x,y,z);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(Integer)