POJ 3468 A Simple Problem with Integers

POJ 3468 A Simple Problem with Integers

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 a b c” means adding c to each of Aa, Aa+1, … , Ab. -10000 ≤ c ≤ 10000.
“Q a b” 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

Hint

The sums may exceed the range of 32-bit integers.

额,简单的线段树区间维护,最后那个hint一直没看到,哭了……

#include 
#include
#include
using namespace std;
typedef long long ll;

ll tree[400005],Add[400005];

void pushup(int i)
{
    tree[i]=tree[2*i]+tree[2*i+1];
}

void pushdown(int i,int l)
{
    if(Add[i])
       {
          Add[2*i]+=Add[i];
          Add[2*i+1]+=Add[i];
          tree[2*i]+=Add[i]*(l-l/2);
          tree[2*i+1]+=Add[i]*(l/2);
          Add[i]=0;
       }
}

void build(int i,int l,int r)
{
    if (l==r) {
            scanf("%lld",&tree[i]);
        return ;
    }
    int mid=l+(r-l)/2;
    build(2*i,l,mid);
    build(2*i+1,mid+1,r);
    pushup(i);
}

void add(int i,int l,int r,int x,int y,int k)
{
    if(x<=l && r<=y)
    {
        Add[i]+=k;
        tree[i]+=(r-l+1)*k;
        return ;
    }
    pushdown(i,r-l+1);
    int mid=l+(r-l)/2;
    if(x<=mid) add(2*i,l,mid,x,y,k);
    if(y>mid) add(2*i+1,mid+1,r,x,y,k);
    pushup(i);
}

ll query(int i,int l,int r,int m,int n)
{
    ll sum=0;
    if(m<=l && r<=n){
        return tree[i];
    }
    pushdown(i,r-l+1);//查询时也要将附加值向下传递,否则WA
    int mid=l+(r-l)/2;
    if (m<=mid) sum+=query(2*i,l,mid,m,n);
    if (n>mid) sum+=query(2*i+1,mid+1,r,m,n);
    return sum;
}

int main()
{
    ll m,n,x,y,k;
    char t;
    cin>>n>>m;
    build(1,1,n);
    while(m--)
    {
        cin>>t;
        if(t=='Q')
        {
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",query(1,1,n,x,y));
        }
        else
            {
              scanf("%lld%lld%lld",&x,&y,&k);
              add(1,1,n,x,y,k);
            }
    }
}

你可能感兴趣的:(POJ,线段树)