• CF396C On Changing Tree


    Solution

    每个子树都对应DFS序上的一段区间。
    发现所有操作要么只针对子树,要么只针对单个节点,因此我们可以利用DFS序将树上的操作转化为区间上的操作。
    当我们更新节点 (u) 时,对于他的子节点 (i),它的变化值为(x-(dep[i]-dep[u])*k=x+dep[u]*k-dep[i]*k),我们只用记录(x+dep[u]*k)(k),最后就能算出答案。
    用树状数组优化一下就过了。
    因为树状数组或线段树的特性,想要利用它们优化区间更新,就需要找到该区间内每个元素相同的变化量。

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 3e5 + 10;
    const int MOD = 1e9 + 7;
    
    vector<int> e[MAXN];
    long long c1[MAXN],c2[MAXN],n,q,siz[MAXN],dep[MAXN],num[MAXN],cnt;
    
    inline int lowbit(int x) {
        return (x & -x);
    }
    
    void update(long long x,long long val,long long k) {
        for (int i = x; i <= n; i += lowbit(i)) {
            c1[i] = (c1[i] + val) % MOD;c2[i] = (c2[i] + k) % MOD;
        }
    }
    
    long long query(int x,int u) {
        int sum1 = 0,sum2 = 0;
        for (int i = x; i > 0; i -= lowbit(i)) {
            sum1 = (sum1 + c1[i]) % MOD;sum2 = (sum2 + c2[i]) % MOD;
        }
        return ((sum1 - dep[u] * sum2) % MOD + MOD) % MOD;
    }
    
    void DFS(int u,int fa) {
        num[u] = ++cnt;
        int len = e[u].size();dep[u] = dep[fa] + 1;siz[u] = 1;
        for (int i = 0; i < len; i++) {
            DFS(e[u][i],u);
            siz[u] += siz[e[u][i]];
        }
        return;
    }
    
    int main() {
        scanf("%d",&n);
        for (int i = 2; i <= n; i++) {
            int u;
            scanf("%d",&u);
            e[u].push_back(i);
        }
        DFS(1,0);
        scanf("%d",&q);
        for (int i = 1; i <= q; i++) {
            int type;scanf("%d",&type);
            if (type == 1) {
                long long u,x,k;
                scanf("%lld%lld%lld",&u,&x,&k);
                update(num[u],(x + dep[u] * k) % MOD,k);
                update(num[u] + siz[u],-(x + dep[u] * k) % MOD,-k);
            }
            if (type == 2) {
                int u;
                scanf("%d",&u);
                printf("%lld
    ",query(num[u],u));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    青浦图书志
    师徒俩就这样比划着 讲着该怎么去使用Reactor Programming
    Stephane Maldini and Violeta Georgieva at SpringOne Platform 2019
    reactor 大会
    这样使用Mono.zip就可以合并多个值进行下一步运算
    You are totally right 和 You are absolutely right 区别
    reacctor 1
    developer.ibm.com
    zip~~~~~~~~~~~
    044 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 06 使用do-while循环实现猜字游戏
  • 原文地址:https://www.cnblogs.com/kjd123456/p/15092327.html
Copyright © 2020-2023  润新知