树的区间查询与更新(线段树)

来源:互联网 发布:listview的优化方案 编辑:程序博客网 时间:2024/05/13 15:24

原题:http://oj.51isoft.com/bnuoj/problem_show.php?pid=14223

#include <iostream>#include <stdio.h>#include <string.h>#include <map>#include <math.h>#include <set>#include <vector>#include <algorithm>using namespace std;#define CLR(x) memset(x,0,sizeof(x))#define LL long long#define typec double#define lson l , m , rt << 1#define rson m+1 , r , rt << 1 | 1const int N = 100000;LL add[N<<2];LL sum[N<<2];void PushUp(int rt){    sum[rt]=sum[rt << 1] + sum[rt<<1 | 1];}void PushDown(int rt,int m){    if (add[rt]){        add[rt<<1]+=add[rt];        add[rt<<1 | 1]+=add[rt];        sum[rt<<1] += (add[rt] * (m-(m>>1)));        sum[rt<<1 | 1]+=add[rt]*(m>>1);        add[rt]=0;    }}void build(int l,int r,int rt){    add[rt]=0;    if (l==r){        sum[rt]=0;        return;    }    int m=(l + r)>>1;    build(lson);    build(rson);    PushUp(rt);}LL ans[N];void output(int l,int r,int rt){    if (l==r){        ans[l]=sum[rt];        return;    }    PushDown(rt,r-l+1);    int m=(l+r)>>1;    output(lson);    output(rson);    PushUp(rt);}void update(int L ,int R,LL c,int l,int r,int rt){    if (L<=l && r<=R){        add[rt]+=c;        sum[rt]+=c*(r-l+1LL);        return;    }    PushDown(rt,r-l+1);    int m=(l + r)>>1;    if (L<=m) update(L,R,c,lson);    if (m<R) update(L,R,c,rson);    PushUp(rt);}LL query(int L ,int R ,int l ,int r ,int rt){    if (L<=l && r<=R)        return sum[rt];    PushDown(rt,r-l+1);    int m=(l + r)>>1;    LL ret=0;    if (L<=m) ret+=query(L,R,lson);    if (m<R) ret+=query(L,R,rson);    return ret;}LL pay[N];int n,m;char str[100];int head[N],tot;int order[N][2],o;struct E{    int to,next;}edge[N];void addedge(int a,int b){    edge[tot].to=b;    edge[tot].next=head[a];    head[a]=tot++;}int dfs(int x){    order[x][0]=++o;order[x][1]=o;    for (int i=head[x];i!=-1;i=edge[i].next){        int temp=dfs(edge[i].to);        order[x][1]=temp;    }    return order[x][1];}void solve(){    memset(head,-1,sizeof(head));    tot=0;    for (int i=1;i<n;++i){        int temp;        scanf("%d%lld",&temp,&pay[i]);        addedge(temp,i);    }    o=0;    dfs(0);    build(1,n,1);    for (int i=0;i<n;++i)        update(order[i][0],order[i][0],pay[i],1,n,1);    while(m--){        int a;LL b,c;        scanf("%s%d%lld%lld",str,&a,&b,&c);        if (str[0]=='e'){            LL res=query(order[a][0],order[a][0],1,n,1);            if (res<b) update(order[a][0],order[a][0],c,1,n,1);        }        else{            LL res=query(order[a][0],order[a][1],1,n,1);            if (res<b*(order[a][1]-order[a][0]+1LL)) update(order[a][0],order[a][1],c,1,n,1);        }    }    output(1,n,1);    for (int i=0;i<n;++i)        printf("%lld\n",ans[order[i][0]]);}int main(){   // freopen("in","r",stdin);    while (~scanf("%d%d%lld",&n,&m,&pay[0])) solve();}

原创粉丝点击