线段树 POJ 3468 A Simple Problem with Integers

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 abc" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q ab" 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<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
long long a[100217*4];
long long col[100217*4];
int temp=1;
void build(int rt, int begin, int end)
{
    int m=(begin+end)/2;
    if(begin==end)
    {
        scanf("%I64d",&a[rt]);
        return ;
    }
    build( rt << 1, begin, m);
    build( 1 + (rt << 1), m + 1,end);
    a[rt] = a[rt << 1] + a[1 + (rt << 1)];
}
void update(int rt, int begin, int end, int x, int y, int v)
{
    int m=(begin+end)/2;
    if(x>end||y<begin)
        return ;
    if(end<=y&&begin>=x)
    {
        a[rt]+=(end-begin+1)*v;
        col[rt]+=v;
        //printf("%d %d %d %d %d\n",col[rt], begin, end, rt, a[rt]);
        return ;
    }
    if(col[rt]!=0)
    {
        a[rt<<1] += (m-begin+1)*col[rt];
        a[(rt<<1)+1] += (end-(m+1)+1)*col[rt];
        col[rt<<1] += col[rt] ;
        col[(rt<<1)+1] += col[rt] ;
        col[rt] = 0;
    }
    update( rt << 1, begin, m, x, y, v);
    update( 1 + (rt << 1), m + 1,end, x, y, v);
    a[rt] = a[rt << 1] + a[1 + (rt << 1)];
}
long long query(int rt, int begin, int end, int x, int y)
{

    int m=(begin+end)/2;
    if(x>end||y<begin)
        return 0;
    if(end<=y&&begin>=x)
    {
        //printf("%d-\n",rt);
        //printf("%d\n",a[rt]);
       long long t=a[rt];
        return t;
    }
    if(col[rt]!=0)
    {
        a[rt<<1 ]+= (m-begin+1)*col[rt];
        a[(rt<<1)+1] += (end-(m+1)+1)*col[rt];
        col[rt<<1] += col[rt] ;
        col[(rt<<1)+1] += col[rt] ;
        col[rt] = 0;
    }
    long long p1 = 0,p2 = 0;
    p1 = query( rt << 1, begin, m, x, y);
    p2 = query( 1 + (rt << 1), m + 1,end, x, y);
    //printf("%d %d\n",p1,p2);
    return p1+p2;
    //a[rt]=a[rt << 1] + a[1 + (rt << 1)];
}
int main()
{
    int T,n,m;
    while(scanf("%d%d",&n,&m)!=-1)
    {
        build(1,1,n);
       // puts("1");
        memset(col,0,sizeof(col));
       // getchar();
       // printf("%d\n",a[1]);
       while(m--)
       {
           //getchar();
           int x,y,v;
           char ch[10];
           scanf("%s",&ch);
           //printf("%c\n",ch);
           if(ch[0]=='Q')
           {
               scanf("%d%d", &x, &y);
               printf("%lld\n", query(1,1,n,x,y));
              // puts("y");
//               for(int i=1;i<n*4;i++)
//                    printf("%I64d %d\n",a[i],i);
           }
           else
           {
               //puts("x");
               scanf("%d%d%d", &x, &y, &v);
                update(1,1,n,x,y,v);
                //printf("%d\n",a[1]);
//                for(int i=1;i<n*4;i++)
//                    printf("%I64d %d\n",a[i],i);
           }
       }

    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值