poj 3468

来源:互联网 发布:风云纯网络防火墙 编辑:程序博客网 时间:2024/06/04 18:15

题目

区间更新,区间求和。

多了lazy标记,更新是,把当前断更新,再把lazy标记向下更新,这就是pushdown的作用。

代码如下:

#include<iostream>#include<algorithm>#include<cstdio>using namespace std;#define maxn 100005#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct Tree{    int l,r;    __int64 num,lazy;}tree[maxn<<2];void PushUp(int rt){    tree[rt].num=tree[rt<<1].num+tree[rt<<1|1].num;}void PushDown(int rt){    if(tree[rt].lazy){        tree[rt<<1].lazy+=tree[rt].lazy;        tree[rt<<1|1].lazy+=tree[rt].lazy;        tree[rt<<1].num+=tree[rt].lazy*(tree[rt<<1].r-tree[rt<<1].l+1);        tree[rt<<1|1].num+=tree[rt].lazy*(tree[rt<<1|1].r-tree[rt<<1|1].l+1);        tree[rt].lazy=0;    }}void build(int l,int r,int rt){    tree[rt].l=l;    tree[rt].r=r;    tree[rt].lazy=0;    if(l==r){        scanf("%I64d",&tree[rt].num);        return ;    }    int m=(l+r)>>1;    build(lson);    build(rson);    PushUp(rt);}void update(int x,int y,__int64 val,int rt){    int l,r;    l=tree[rt].l;    r=tree[rt].r;    if(l==x&&r==y){        tree[rt].lazy+=val;        tree[rt].num+=(r-l+1)*val;        return ;    }    PushDown(rt);    int m=(l+r)>>1;    if(x<=m) update(x,min(m,y),val,rt<<1);    if(y>m) update(max(m+1,x),y,val,rt<<1|1);    PushUp(rt);}__int64 query(int x,int y,int rt){    int l,r;    l=tree[rt].l;    r=tree[rt].r;    if(l==x&&r==y){        return tree[rt].num;    }    PushDown(rt);    __int64 ans=0;    int m=(l+r)>>1;    if(x<=m) ans+=query(x,min(y,m),rt<<1);    if(y>m) ans+=query(max(m+1,x),y,rt<<1|1);    return ans;}int main(){    int n,m;    scanf("%d%d",&n,&m);    build(1,n,1);    while(m--){        char str[5];        int a,b;        __int64 c;        scanf("%s",str);        if(str[0]=='Q'){            scanf("%d%d",&a,&b);            printf("%I64d\n",query(a,b,1));        }        else{            scanf("%d%d%I64d",&a,&b,&c);            update(a,b,c,1);        }    }    return 0;}


原创粉丝点击