zoukankan      html  css  js  c++  java
  • 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;
        }
    };
  • 相关阅读:
    wikioi 1002 旁路
    OS X升级到10.10使用后pod故障解决方案出现
    Python challenge 3
    maven 编
    独立博客网站FansUnion.cn操作2多年的经验和教训以及未来计划
    Wakelock API详解
    智遥工作流——会签与多人审批区别
    mysql 参数optimizer_switch
    OpenRisc-31-关于在设计具有DMA功能的ipcore时的虚实地址转换问题的分析与解决
    TROUBLE SHOOTING: FRM-30425
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/12690135.html
Copyright © 2011-2022 走看看