poj 3468 A Simple Problem with Integers (线段树---成段更新)

来源:互联网 发布:淘宝贷款利息多少 编辑:程序博客网 时间:2024/05/24 06:30

成段加减

que里面也有pushdown函数  \(^o^)/

水题!


#include<cstdio>#include<iostream>#define maxn 100010using namespace std;typedef long long ll;ll sum[maxn<<2],lazy[maxn<<2];void pushdown(int rt,int m){    if(lazy[rt])    {        lazy[rt<<1] += lazy[rt];        lazy[rt<<1|1] += lazy[rt];        sum[rt<<1] += lazy[rt]*(m-(m>>1));        sum[rt<<1|1] += lazy[rt]*(m>>1);        lazy[rt] = 0;    }}void pushup(int rt){    sum[rt] = sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){    lazy[rt] = 0; // 每一个节点都要lazy清空    if(l==r)    {        scanf("%I64d",&sum[rt]); //读入叶子节点的信息        return;    }    int mid = (l+r)>>1;    build(l,mid,rt<<1);    build(mid+1,r,rt<<1|1);    pushup(rt);}void update(int le,int ri,int v,int l,int r,int rt){    if(le<=l && r<=ri)    {        lazy[rt] += v;  //这里是+=,因为可能多次update时,前一次的还没有下传        sum[rt] += (ll)v*(r-l+1);        return;    }    pushdown(rt,r-l+1);    int mid = (l+r)>>1;    if(le<=mid) update(le,ri,v,l,mid,rt<<1);    if(ri>mid) update(le,ri,v,mid+1,r,rt<<1|1);    pushup(rt);}ll que(int le,int ri,int l,int r,int rt){    if(le<=l && r<=ri)    {        return sum[rt];    }    pushdown(rt,r-l+1);  //这里也要向下更新    int mid = (l+r)>>1;    ll ret = 0;    if(le<=mid) ret+=que(le,ri,l,mid,rt<<1);    if(ri>mid) ret+=que(le,ri,mid+1,r,rt<<1|1);    return ret;}int main(){    int n,q,a,b,c;    char op[2];    while(scanf("%d%d",&n,&q)!=EOF)    {        build(1,n,1);        while(q--)        {            scanf("%s",op);            if(op[0]=='C')            {                scanf("%d%d%d",&a,&b,&c);                update(a,b,c,1,n,1);            }            else            {                scanf("%d%d",&a,&b);                printf("%I64d\n",que(a,b,1,n,1));            }        }    }    return 0;}



0 0
原创粉丝点击