Change FZU - 2277 毒瘤啊 毒瘤题目

Posted qldabiaoge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Change FZU - 2277 毒瘤啊 毒瘤题目相关的知识,希望对你有一定的参考价值。

There is a rooted tree with n nodes, number from 1-n. Root’s number is 1.Each node has a value ai.

Initially all the node’s value is 0.

We have q operations. There are two kinds of operations.

1 v x k : a[v]+=x , a[v’]+=x-k (v’ is child of v) , a[v’’]+=x-2*k (v’’ is child of v’) and so on.

2 v : Output a[v] mod 1000000007(10^9 + 7).

Input

First line contains an integer T (1 ≤ T ≤ 3), represents there are T test cases.

In each test case:

The first line contains a number n.

The second line contains n-1 number, p2,p3,…,pn . pi is the father of i.

The third line contains a number q.

Next q lines, each line contains an operation. (“1 v x k” or “2 v”)

1 ≤ n ≤ 3*10^5

1 ≤ pi < i

1 ≤ q ≤ 3*10^5

1 ≤ v ≤ n; 0 ≤ x < 10^9 + 7; 0 ≤ k < 10^9 + 7

Output

For each operation 2, outputs the answer.

Sample Input

1
3
1 1
3
1 1 2 1
2 1
2 2

Sample Output

2
1
题意
节点u加x,节点u的儿子u′加x−k,节点u的孙子u′′加x−2×k,依次类推。 

看数据范围标准的线段树
但是这个k不好处理 这个k和深度有关系
所以这题在初始化处理的时候 1LL * x + 1LL * dep[v]*k
这样就便于我们查询了

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <set>
  7 #include <iostream>
  8 #include <map>
  9 #include <stack>
 10 #include <string>
 11 #include <vector>
 12 #define  rtl         rt<<1
 13 #define  rtr         rt<<1|1
 14 #define  mem(a,b)    memset(a,b,sizeof(a))
 15 #define  fuck(x)     cout<<"["<<x<<"]"<<endl
 16 #define  sf(n)       scanf("%d", &n)
 17 #define  sff(a,b)    scanf("%d %d", &a, &b)
 18 #define  sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
 19 #define  sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
 20 #define  FIN         freopen("DATA.txt","r",stdin)
 21 #define read(x) scanf("%d", &x)
 22 using namespace std;
 23 typedef long long LL;
 24 const int maxn = 1e6 + 10;
 25 const int mod = 1e9 + 7;
 26 int t, n, q, tot, dfscnt, head[maxn], L[maxn], R[maxn], dep[maxn];
 27 struct Edge {
 28     int v, nxt;
 29 } edge[maxn << 1];
 30 void add(int u, int v) {
 31     edge[tot].v = v;
 32     edge[tot].nxt = head[u];
 33     head[u] = tot++;
 34 }
 35 void dfs(int u, int fa, int d) {
 36     L[u] = ++dfscnt;
 37     dep[u] = d;
 38     for (int i = head[u] ; ~i ; i = edge[i].nxt) {
 39         int v = edge[i].v;
 40         if (v != fa) dfs(v, u, d + 1);
 41     }
 42     R[u] = dfscnt;
 43 }
 44 struct node {
 45     int l, r;
 46     LL num, k;
 47     int mid() {
 48         return (l + r) >> 1;
 49     }
 50 } tree[maxn << 2];
 51 void build(int l, int r, int rt) {
 52     tree[rt].l = l, tree[rt].r = r;
 53     tree[rt].num = tree[rt].k = 0;
 54     if (l == r) return ;
 55     int m = (l + r) >> 1;
 56     build(l, m, rtl);
 57     build(m + 1, r, rtr);
 58 }
 59 void pushdown(int rt) {
 60     if (tree[rt].num != 0) {
 61         tree[rtl].num = (tree[rt].num + tree[rtl].num) % mod;
 62         tree[rtr].num = (tree[rt].num + tree[rtr].num) % mod;
 63         tree[rt].num = 0;
 64     }
 65     if (tree[rt].k != 0) {
 66         tree[rtl].k = (tree[rt].k + tree[rtl].k) % mod;
 67         tree[rtr].k = (tree[rt].k + tree[rtr].k) % mod;
 68         tree[rt].k = 0;
 69     }
 70 }
 71 
 72 void update(LL a, LL b, int L, int R, int rt) {
 73     if (L <= tree[rt].l && tree[rt].r <= R) {
 74         tree[rt].num = ((tree[rt].num + a) % mod + mod) % mod;
 75         tree[rt].k = ((tree[rt].k + b) % mod + mod) % mod;
 76         return ;
 77     }
 78     pushdown(rt);
 79     int mid = tree[rt].mid();
 80     if (R <= mid) update(a, b, L, R, rtl);
 81     else if(L > mid) update(a, b, L, R, rtr);
 82     else {
 83         update(a, b, L, mid, rtl);
 84         update(a, b, mid + 1, R, rtr);
 85     }
 86 }
 87 LL query(int pos, int d, int rt) {
 88     if (tree[rt].l == tree[rt].r) {
 89         return ((tree[rt].num - d * tree[rt].k % mod) % mod + mod) % mod;
 90     }
 91     pushdown(rt);
 92     int mid = tree[rt].mid();
 93     if (pos <= mid) return query(pos, d, rtl);
 94     return query(pos, d, rtr);
 95 }
 96 int main() {
 97     int op, v, x, k;
 98     sf(t);
 99     while(t--) {
100         sf(n);
101         for (int i = 0 ; i <= n ; i++) head[i] = -1;
102         tot = 0;
103         for (int i = 2 ; i <= n ; i++) {
104             sf(v);
105             add(v, i);
106             add(i, v);
107         }
108         dfscnt = 0;
109         dfs(1, -1, 1);
110         build(1, n, 1);
111         sf(q);
112         while(q--) {
113             sf(op);
114             if (op == 1) {
115                 sfff(v, x, k);
116                 update(1LL * x + 1LL * dep[v]*k, k, L[v], R[v], 1);
117             } else {
118                 sf(v);
119                 printf("%lld
", query(L[v], dep[v], 1));
120             }
121         }
122     }
123     return 0;
124 }

 



以上是关于Change FZU - 2277 毒瘤啊 毒瘤题目的主要内容,如果未能解决你的问题,请参考以下文章

FZU 2277Change

FZU 2277 树状数组

HDU 2277 Change the ball

网络流(毒瘤)学习总结1

FZU 2020 组合 (Lucas定理)

FZU 2113 BCD Code 数位dp