LCP 5. 发 LeetCoin

link

 

 解法:

先DFS给每个节点一个id,然后可以获得每个节点这颗子树的区间(一定是连续的),这样就可以进行线段树的操作(单点修改,区间修改,和区间查询),

 

#define LL long long
const int maxn=50005;
const int mod=1000000007;

class Solution {
public:
    int cnt;
    int N;
    LL sum[maxn<<2], lazy[maxn<<2];
    int in[maxn],out[maxn];
    vector<int> adj[maxn];

    void update_range(int tleft, int tright, int left, int right, int idx, int val){
        if(tleft>right || tright<left) return;
        if(tleft<=left && tright>=right){
            sum[idx]=(sum[idx]+val*(right-left+1)%mod)%mod;
            lazy[idx]=(lazy[idx]+val)%mod;
            return;
        }
        push_down(idx,left,right);
        int mid=(left+right)>>1;
        update_range(tleft,tright,left,mid,idx*2,val);
        update_range(tleft,tright,mid+1,right,idx*2+1,val);
        sum[idx]=(sum[idx*2]+sum[idx*2+1])%mod;
    }

    void update_single(int targetidx, int left, int right, int idx, int val){
        if(left>targetidx || right<targetidx) return;
        if(left==right) {
            sum[idx]+=val;
            sum[idx]%=mod;
            return;
        }
        push_down(idx,left,right);
        int mid=(left+right)/2;
        update_single(targetidx,left,mid,idx*2,val);
        update_single(targetidx,mid+1,right,idx*2+1,val);
        sum[idx]=(sum[idx*2]+sum[idx*2+1])%mod;
    }

    void push_down(int idx, int left, int right){
        int mid=(left+right)/2;
        sum[idx*2]=(sum[idx*2]+lazy[idx]*(mid-left+1)%mod)%mod;
        sum[idx*2+1]=(sum[idx*2+1]+lazy[idx]*(right-(mid+1)+1)%mod)%mod;
        lazy[idx*2]=(lazy[idx*2]+lazy[idx])%mod;
        lazy[idx*2+1]=(lazy[idx*2+1]+lazy[idx])%mod;
        lazy[idx]=0;
    }

    LL query(int qleft, int qright, int left, int right, int idx){
        if(qleft>right || qright<left) return 0;
        if(qleft<=left && qright>=right){
            return sum[idx];
        }
        push_down(idx,left,right);
        LL res=0;
        int mid=(left+right)>>1;
        LL l=query(qleft,qright,left,mid,idx*2);
        LL r=query(qleft,qright,mid+1,right,idx*2+1);
        res=(l+r)%mod;
        return res;
    }

    vector<int> bonus(int n, vector<vector<int>>& leadership, vector<vector<int>>& operations) {
        N=n;
        cnt=0;
        for(auto l:leadership){
            adj[l[0]].push_back(l[1]);
        }
        dfs(1);
        vector<int> res;
        for(auto ope:operations){
            if(ope[0]==1){
                update_single(in[ope[1]],1,cnt,1,ope[2]);
            }else if(ope[0]==2){
                update_range(in[ope[1]],out[ope[1]],1,cnt,1,ope[2]);
            }else {
                LL ret=query(in[ope[1]],out[ope[1]],1,cnt,1);
                ret%=mod;
                res.push_back(ret);
            }
        }
        return res;
    }

    void dfs(int u){
        in[u]=++cnt;
        for(int c:adj[u]){
            dfs(c);
        }
        out[u]=cnt;
    }
};

 

posted @ 2020-04-13 11:18  feibilun  阅读(179)  评论(0编辑  收藏  举报