POJ3468(树状数组区间维护)

A Simple Problem with Integers
Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 89818   Accepted: 27967
Case Time Limit: 2000MS

Description

You have N integers, A1A2, ... , 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 A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+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 <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int MAXN=100005;
struct Node{
    ll sum,lazy;
    int l,r;
};
struct SegmentTree{
private:
    Node a[MAXN*4];
public:
    void build(int rt,int l,int r)
    {
        a[rt].l=l;
        a[rt].r=r;
        a[rt].lazy=0;
        if(l==r)
        {
            scanf("%lld",&a[rt].sum);
            return ;
        }
        int mid=(a[rt].l+a[rt].r)>>1;
        build(rt<<1,l,mid);
        build(rt*2+1,mid+1,r);
        a[rt].sum=a[rt<<1].sum+a[rt*2+1].sum;
    }
    void pushDown(int rt)
    {
        int mid=(a[rt].l+a[rt].r)>>1;
        a[rt<<1].sum+=(mid-a[rt].l+1)*a[rt].lazy;
        a[rt*2+1].sum+=(a[rt].r-mid)*a[rt].lazy;
        a[rt<<1].lazy+=a[rt].lazy;
        a[rt*2+1].lazy+=a[rt].lazy;
        a[rt].lazy=0;
    }
    void change(int rt,int l,int r,int val)
    {
        if(a[rt].l==l&&a[rt].r==r)
        {
            a[rt].sum+=(r-l+1)*val;
            a[rt].lazy+=val;
            return ;
        }
        if(a[rt].lazy!=0)
        {
            pushDown(rt);
        }
        int mid=(a[rt].l+a[rt].r)>>1;
        if(r<=mid)
        {
            change(rt<<1,l,r,val);
        }
        else if(mid<l)
        {
            change(rt*2+1,l,r,val);
        }
        else
        {
            change(rt<<1,l,mid,val);
            change(rt*2+1,mid+1,r,val);
        }
        a[rt].sum=a[rt<<1].sum+a[rt*2+1].sum;
    }
    ll query(int rt,int l,int r)
    {
        if(a[rt].l==l&&a[rt].r==r)
        {
            return a[rt].sum;
        }
        if(a[rt].lazy!=0)
        {
            pushDown(rt);
        }
        int mid=(a[rt].l+a[rt].r)>>1;
        if(r<=mid)
            return query(rt<<1,l,r);
        else if(mid<l)
            return query(rt*2+1,l,r);
        else
        {
            return query(rt<<1,l,mid)+query(rt*2+1,mid+1,r);
        }
    }
};
SegmentTree solver;
int n,m;
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        solver.build(1,1,n);
        for(int i=0;i<m;i++)
        {
            scanf("%*c");
            char op;
            scanf("%c",&op);
            if(op=='Q')
            {
                int l,r;
                scanf("%d%d",&l,&r);
                printf("%lld\n",solver.query(1,l,r));
            }
            else
            {
                int l,r,val;
                scanf("%d%d%d",&l,&r,&val);
                solver.change(1,l,r,val);
            }
        }
    }
    
    return 0;
}

 

posted on 2015-11-22 15:03  vCoders  阅读(849)  评论(0编辑  收藏  举报

导航