P7746 PLAĆE 题解

· · 题解

题目大意

给定一棵初始权值已知的树,每次操作:

  1. 对某个节点子树上的所有节点加上 x
  2. 查询某个节点的权值。

具体思路

Code

  #include<bits/stdc++.h>
  #define int long long
  #define maxn 1000005
  #define maxm 1000005
  using namespace std;

    inline int read(){
        int x=0,w=1;
        char ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        return x*w;
    }

    int cnt,n,m,k,tot=1;
    int head[maxn],h[maxn],t[maxn],num[maxn],c[maxn];
    struct e{int to,next;}edge[maxm];
    int tree[maxn];

    inline void addedge(int u,int v){
        edge[++cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt;
    }

    void dfs(int x){
        h[x]=++tot;
        for(int i=head[x];i;i=edge[i].next)
            dfs(edge[i].to);
        t[x]=++tot;
    }

    inline int lowbit(int x){
        return x&-x;
    }

    void add(int x,int k){
        while(x<=tot){
            c[x]+=k;
            x+=lowbit(x);
        }
    }

    int query(int x){
        int sum=0;
        while(x){
            sum+=c[x];
            x-=lowbit(x);
        }
        return sum;
    }

    signed main(){
        n=read();m=read();
        tree[1]=read();
        for(int i=2;i<=n;++i){
            tree[i]=read();
            int x=read();
            addedge(x,i);
        }
        dfs(1);
        for(int i=1;i<=m;++i){
            char opt;
            cin>>opt;
            if(opt=='p'){
                int a=read(),x=read();
                add(h[a]+1,x);
                add(t[a],-x);
            }
            else{
                int a=read();
                printf("%d\n",tree[a]+query(h[a]));
            }
        }
        return 0;
    }

码风比较丑,还请见谅。