POJ 3468 A Simple Problem with Integers

来源:互联网 发布:淘宝客服奖罚 编辑:程序博客网 时间:2024/04/30 02:25

一般说简单的题目不简单,但是有了线段树之后这些题都是简单题~~~


题目大意:

给定N个数的序列,有Q个操作。操作分两种:1、将某个区间内的所有数都加上某个数。2、计算某个区间的所有数之和并输出。


解题思路:

简单的线段树。单点更新会TLE,只能区间更新。


下面是代码:

#include <stdio.h>#include <string.h>#include <iostream>#define BigInteger long longusing namespace std;const int Max=100000;struct nodenode{    BigInteger sum,val;} node[Max<<2];void PushUp(int tr){    node[tr].sum=node[tr<<1].sum+node[tr<<1|1].sum;}void PushDown(int tr,int m){    if(node[tr].val)    {        node[tr<<1].val+=node[tr].val;        node[tr<<1|1].val+=node[tr].val;        node[tr<<1].sum+=(BigInteger)(m-(m>>1))*node[tr].val;        node[tr<<1|1].sum+=(BigInteger)(m>>1)*node[tr].val;        node[tr].val=0;    }}void Build(int l,int r,int tr){    node[tr].val=0;    if(l==r)    {        scanf("%I64d",&node[tr].sum);        return ;    }    int m=(l+r)>>1;    Build(l,m,tr<<1);    Build(m+1,r,tr<<1|1);    PushUp(tr);}BigInteger query(int L,int R,int l,int r,int tr){    if(L<=l&&r<=R)    {        return node[tr].sum;    }    int m=(l+r)>>1;    PushDown(tr,r-l+1);    BigInteger ans=0;    if(L<=m)ans+=query(L,R,l,m,tr<<1);    if(m<R)ans+=query(L,R,m+1,r,tr<<1|1);    PushUp(tr);    return ans;}void Update(int L,int R,int add,int l,int r,int tr){    if(L<=l&&r<=R)    {        node[tr].sum+=(BigInteger)add*(r-l+1);        node[tr].val+=add;        return ;    }    PushDown(tr,r-l+1);    int m=(l+r)>>1;    if(L<=m)Update(L,R,add,l,m,tr<<1);    if(m<R)Update(L,R,add,m+1,r,tr<<1|1);    PushUp(tr);}int main(){    int n,q,a,b;    BigInteger c;    while(scanf("%d%d",&n,&q)!=EOF)    {        Build(1,n,1);        char s[3];        while(q--)        {            scanf("%s",s);            if(s[0]=='Q')            {                cin >>a>>b;                cout <<query(a,b,1,n,1)<<endl;            }            else if(s[0]=='C')            {                cin >>a>>b>>c;                Update(a,b,c,1,n,1);            }        }    }    return 0;}


0 0