poj 3468 向上和向下传递

来源:互联网 发布:羊绒围巾推荐知乎 编辑:程序博客网 时间:2024/05/14 15:40

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 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 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<stdio.h>#define N 100001#define L(i) i<<1#define R(i) i<<1|1/*关键:向上和向下传递*/struct node{    int left,right;    long long sum, //区间和     value;//标记值    int mid(){return (left+right)/2;}    int len(){return (right-left+1);}}st[N<<2];long long a[N],s[N];void build(int left,int right,int id){    st[id].left=left;    st[id].right=right;    st[id].value=st[id].sum=0;    if(left==right)    {        st[id].sum=a[st[id].left];        return;    }    int mid=st[id].mid();    build(left,mid,L(id));    build(mid+1,right,R(id));    st[id].sum=st[L(id)].sum+st[R(id)].sum;}void update(int left,int right,int k,int id){    if(left==st[id].left&&st[id].right==right)    {        st[id].value+=k;        st[id].sum+=st[id].len()*k;        return ;    }    //向下更新    if(st[id].value)    {        st[L(id)].value+=st[id].value;        st[R(id)].value+=st[id].value;        st[L(id)].sum+=st[id].value*st[L(id)].len();        st[R(id)].sum+=st[id].value*st[R(id)].len();        st[id].value=0;    }    int mid=st[id].mid();    if(mid>=right)        update(left,right,k,L(id));    else if(mid<left)        update(left,right,k,R(id));    else    {        update(left,mid,k,L(id));        update(mid+1,right,k,R(id));    }    st[id].sum=st[L(id)].sum+st[R(id)].sum;}long long query(int left,int right,int id){    if(st[id].left==left&&st[id].right==right)        return st[id].sum;    //向下更新    if(st[id].value)    {        st[L(id)].value+=st[id].value;        st[R(id)].value+=st[id].value;        st[L(id)].sum+=st[id].value*st[L(id)].len();        st[R(id)].sum+=st[id].value*st[R(id)].len();        st[id].value=0;    }    int mid=st[id].mid();    if(mid>=right)        return query(left,right,L(id));    else if(mid<left)        return query(left,right,R(id));    return query(left,mid,L(id))+query(mid+1,right,R(id));}int main(){    int n,q,i,aa,b,c;    scanf("%d%d",&n,&q);    for(i=1;i<=n;++i)    {        scanf("%lld",&a[i]);    }    build(1,n,1);    char cc[2];    while(q--)    {        scanf("%s",cc);        if(cc[0]=='Q')        {            scanf("%d%d",&aa,&b);            printf("%lld\n",query(aa,b,1));        }        else        {            scanf("%d%d%d",&aa,&b,&c);            update(aa,b,c,1);        }    }    return 0;}/*10 101 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4*/


原创粉丝点击