51nod 1199 Money out of Thin Air[线段树]

来源:互联网 发布:产品说明书排版软件 编辑:程序博客网 时间:2024/05/18 01:12

题面
把树按dfs序搞成序列然后直接线段树维护就好了

#include<cstdio>#include<vector>#define N 50000#define LL long longusing namespace std;vector<int>e[N+5];int n,m,fa[N+5],xl[N+5],size,L[N+5],R[N+5];LL sum[N*4+5],lazy[N*4+5],w[N+5];void dfs(int x){    L[x]=++size;xl[size]=x;    for(int i=0;i<e[x].size();++i)        if(e[x][i]!=fa[x]) dfs(e[x][i]);    R[x]=size;}void push(int x,int l,int r){    if(l==r) return;    lazy[x<<1]+=lazy[x];    lazy[x<<1|1]+=lazy[x];    int mid=(l+r)>>1;    sum[x<<1]+=lazy[x]*(mid-l+1);    sum[x<<1|1]+=lazy[x]*(r-mid);    lazy[x]=0;}void build(int x,int l,int r){    if(l==r){        sum[x]=w[xl[l]];        return;    }    int mid=(l+r)>>1;    build(x<<1,l,mid),build(x<<1|1,mid+1,r);    sum[x]=sum[x<<1]+sum[x<<1|1];}void change(int x,int l,int r,int ql,int qr,LL v){    if(lazy[x]) push(x,l,r);    if(l>qr||r<ql) return;    if(l>=ql&&r<=qr){        sum[x]+=1ll*(r-l+1)*v;        lazy[x]+=v;        return;    }    int mid=(l+r)>>1;    change(x<<1,l,mid,ql,qr,v),change(x<<1|1,mid+1,r,ql,qr,v);    sum[x]=sum[x<<1]+sum[x<<1|1];}LL query(int x,int l,int r,int ql,int qr){    if(l>qr||r<ql) return 0;    if(lazy[x]) push(x,l,r);    if(l>=ql&&r<=qr) return sum[x];    int mid=(l+r)>>1;    LL res=query(x<<1,l,mid,ql,qr)+query(x<<1|1,mid+1,r,ql,qr);    sum[x]=sum[x<<1]+sum[x<<1|1];    return res;}int main(){    scanf("%d%d",&n,&m);    for(int i=2;i<=n;++i){        scanf("%d%lld",&fa[i],&w[i]);        ++fa[i];        e[fa[i]].push_back(i);    }    dfs(1);//  for(int i=1;i<=n;++i) change(1,1,size,L[i],L[i],w[i]);    build(1,1,size);    while(m--){        char ch[5];LL x,y,z;        scanf("%s",ch+1);        scanf("%lld%lld%lld",&x,&y,&z);++x;        if(ch[1]=='S'){            LL tmp=query(1,1,size,L[x],L[x]);            if(tmp<1ll*y)                change(1,1,size,L[x],L[x],z);        }        else{            LL tmp=query(1,1,size,L[x],R[x]);            if(tmp<1ll*y*(R[x]-L[x]+1))                change(1,1,size,L[x],R[x],z);        }    }    for(int i=1;i<=n;++i) printf("%lld\n",query(1,1,size,L[i],L[i]));}
原创粉丝点击