poj 3468 (线段树区间更新及求和)

来源:互联网 发布:企业宣传视频制作软件 编辑:程序博客网 时间:2024/05/18 02:35

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

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 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915

Hint

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



# include <cstdio># include <iostream># define MN 400000using namespace std;long long a[100005];struct node{int left,right,mid;long long add,x;}tree[MN];void build(int le,int ri,int num)//构建一个线段树{    tree[num].left= le;    tree[num].right = ri;    tree[num].add = 0;    tree[num].mid = (le + ri) /2;    if(le!=ri)    {        build(le,tree[num].mid,num*2);        build(tree[num].mid+1,ri,num*2+1);        tree[num].x=tree[num*2].x+tree[num*2+1].x;    }    else    {        tree[num].x=a[le];        return ;    }}void change(int le,int ri,int num,int cha)//在一段连续的序列里改变数值{    if(tree[num].left==le&&tree[num].right==ri)    {        tree[num].add += cha;        tree[num].x += cha*(ri-le+1);        return ;    }    if(tree[num].add)    {        tree[num*2].add+=tree[num].add;//将加的数传下去        tree[num*2+1].add += tree[num].add;        tree[2*num].x += tree[num].add*(tree[2*num].right-tree[2*num].left+1);        tree[2*num+1].x += tree[num].add*(tree[2*num+1].right-tree[2*num+1].left+1);        tree[num].add=0;    }    if(ri<=tree[num].mid)        change(le,ri,num*2,cha);    else if(le>tree[num].mid)        change(le,ri,num*2+1,cha);    else    {        change(le,tree[num].mid,num*2,cha);        change(tree[num].mid+1,ri,num*2+1,cha);    }    tree[num].x=(tree[num*2].x + tree[num*2+1].x);//    cout<<"tree["<<num<<"].x"<<tree[num].x<<endl;}long long getsum(int le,int ri,int num)// 求和{    if (le==tree[num].left && ri==tree[num].right)        return tree[num].x ;             // 找到,返回    if(tree[num].add)    {        tree[2*num].add += tree[num].add;        tree[2*num+1].add += tree[num].add;        tree[2*num].x += tree[num].add*(tree[2*num].right-tree[2*num].left+1);        tree[2*num+1].x += tree[num].add*(tree[2*num+1].right-tree[2*num+1].left+1);        tree[num].add = 0;    }    if(le>tree[num].mid)        return getsum(le,ri,2*num+1);    else if(ri<=tree[num].mid)        return getsum(le,ri,2*num);    else    {        return getsum(le,tree[num].mid,2*num)+getsum(tree[num].mid+1,ri,2*num+1);    }}int main(){    int N,Q,i,j;    while(~scanf("%d %d",&N,&Q))    {        for (i=1;i<=N;i++)           scanf("%lld",&a[i]);        getchar();        build(1,N,1);        char T;        int m,t,l,r,c;        for (j=Q;j>0;j--)        {            scanf("%c",&T);            if(T=='Q')            {                scanf("%d%d",&l,&r);                getchar();                cout << getsum(l,r,1) << endl;            }            else {                scanf("%d%d%d",&l,&r,&m);                getchar();                change(l,r,1,m);            }        }    }    return 0;}/*10 221 2 3 4 5 6 7 8 9 10Q 4 4C 1 10 3C 6 10 3C 6 9 3C 8 9 -100C 7 9 3C 7 10 3C 1 10 3Q 6 10Q 6 9Q 8 9Q 7 9Q 7 10Q 1 10Q 2 4C 3 6 3Q 9 9Q 1 1Q 5 5Q 6 6Q 7 7Q 6 84-82-104-147-122-100-3727-737142125-28*/


0 0