zoukankan      html  css  js  c++  java
  • CF396C On Changing Tree

    CF396C On Changing Tree

    给定一棵以 (1) 为根的树,初始时所有点权为 (0)

    (m) 次操作,分为两种

    (1 u x k) 表示给以 (u) 的子树中的每一个点 (v) 点权增加 (x-k imes dis(u, v))

    (2 u) 查询点 (u) 的点权模 (10^9+7) 的值

    (n, mleq3 imes10^5)

    dfs序,树状数组


    把操作 (1) 中的 (dis(u, v)) 拆成 (dep_v-dep_u)(v) 增加的点权即为 (x-k imes(dep_v-dep_u))

    ((x+k imes dep_u)-(k imes dep_v))

    将上式分为 (x+k imes dep_u)(k imes dep_v) 分别维护

    (1) 式可以直接用树状数组维护。因为对于每个 (v)(dep_v) 是定值,所以 (2) 式可以用树状数组维护每个节点的 (k) 来解决

    输出答案时将两式合并即可

    时间复杂度 (O(nlog n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 3e5 + 10, P = 1e9 + 7;
    int n, m, fa[maxn], sz[maxn], tid[maxn], dep[maxn];
    
    inline int inc(int x, int y) {
      return x + y < P ? x + y : x + y - P;
    }
    
    inline int dec(int x, int y) {
      return x - y < 0 ? x - y + P : x - y;
    }
    
    struct BIT {
      int c[maxn];
    
      void add(int pos, int x) {
        for (; pos <= n; pos += pos & -pos) {
          c[pos] = inc(c[pos], x);
        }
      }
    
      int query(int pos) {
        int res = 0;
        for (; pos; pos &= pos - 1) {
          res = inc(res, c[pos]);
        }
        return res;
      }
    
      void add(int l, int r, int x) {
        add(l, x), add(r + 1, dec(0, x));
      }
    } t1, t2;
    
    vector <int> e[maxn];
    
    int dfs(int u) {
      static int now;
      tid[u] = ++now;
      for (int v : e[u]) {
        sz[u] += dfs(v);
      }
      return ++sz[u];
    }
    
    int main() {
      scanf("%d", &n);
      for (int i = 2; i <= n; i++) {
        scanf("%d", fa + i);
        e[fa[i]].push_back(i);
        dep[i] = dep[fa[i]] + 1;
      }
      dfs(1);
      scanf("%d", &m);
      while (m--) {
        int op, u, x, k;
        scanf("%d %d", &op, &u);
        int l = tid[u], r = tid[u] + sz[u] - 1;
        if (op == 1) {
          scanf("%d %d", &x, &k);
          t1.add(l, r, inc(x, 1ll * dep[u] * k % P));
          t2.add(l, r, k);
        } else {
          printf("%d
    ", dec(t1.query(l), 1ll * dep[u] * t2.query(l) % P));
        }
      }
      return 0;
    }
    
  • 相关阅读:
    React 父调子 子调父 observer.js 非父子传值
    echarts 折线图
    跳转新页面解决用户重新登录的方法
    微信小程序规范 引入框架 引入外部js css
    js 400
    Angular2 表单校验
    Angular2 登录页进门户页 用户接口正常 从服务平台退出到门户页 登录接口报302
    CSP-S 2020 SC 迷惑行为大赏
    【题解】[CSP-S 2020] 函数调用【拓扑图DP】
    【题解】[CSP-S 2020] 动物园
  • 原文地址:https://www.cnblogs.com/Juanzhang/p/10783557.html
Copyright © 2011-2022 走看看