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
这样就便于我们查询了
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <set>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <vector>
#define rtl rt<<1
#define rtr rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a))
#define fuck(x) cout<<"["<<x<<"]"<<endl
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define FIN freopen("DATA.txt","r",stdin)
#define read(x) scanf("%d", &x)
using namespace std;
typedef long long LL;
const int maxn = 1e6 + ;
const int mod = 1e9 + ;
int t, n, q, tot, dfscnt, head[maxn], L[maxn], R[maxn], dep[maxn];
struct Edge {
int v, nxt;
} edge[maxn << ];
void add(int u, int v) {
edge[tot].v = v;
edge[tot].nxt = head[u];
head[u] = tot++;
}
void dfs(int u, int fa, int d) {
L[u] = ++dfscnt;
dep[u] = d;
for (int i = head[u] ; ~i ; i = edge[i].nxt) {
int v = edge[i].v;
if (v != fa) dfs(v, u, d + );
}
R[u] = dfscnt;
}
struct node {
int l, r;
LL num, k;
int mid() {
return (l + r) >> ;
}
} tree[maxn << ];
void build(int l, int r, int rt) {
tree[rt].l = l, tree[rt].r = r;
tree[rt].num = tree[rt].k = ;
if (l == r) return ;
int m = (l + r) >> ;
build(l, m, rtl);
build(m + , r, rtr);
}
void pushdown(int rt) {
if (tree[rt].num != ) {
tree[rtl].num = (tree[rt].num + tree[rtl].num) % mod;
tree[rtr].num = (tree[rt].num + tree[rtr].num) % mod;
tree[rt].num = ;
}
if (tree[rt].k != ) {
tree[rtl].k = (tree[rt].k + tree[rtl].k) % mod;
tree[rtr].k = (tree[rt].k + tree[rtr].k) % mod;
tree[rt].k = ;
}
} void update(LL a, LL b, int L, int R, int rt) {
if (L <= tree[rt].l && tree[rt].r <= R) {
tree[rt].num = ((tree[rt].num + a) % mod + mod) % mod;
tree[rt].k = ((tree[rt].k + b) % mod + mod) % mod;
return ;
}
pushdown(rt);
int mid = tree[rt].mid();
if (R <= mid) update(a, b, L, R, rtl);
else if(L > mid) update(a, b, L, R, rtr);
else {
update(a, b, L, mid, rtl);
update(a, b, mid + , R, rtr);
}
}
LL query(int pos, int d, int rt) {
if (tree[rt].l == tree[rt].r) {
return ((tree[rt].num - d * tree[rt].k % mod) % mod + mod) % mod;
}
pushdown(rt);
int mid = tree[rt].mid();
if (pos <= mid) return query(pos, d, rtl);
return query(pos, d, rtr);
}
int main() {
int op, v, x, k;
sf(t);
while(t--) {
sf(n);
for (int i = ; i <= n ; i++) head[i] = -;
tot = ;
for (int i = ; i <= n ; i++) {
sf(v);
add(v, i);
add(i, v);
}
dfscnt = ;
dfs(, -, );
build(, n, );
sf(q);
while(q--) {
sf(op);
if (op == ) {
sfff(v, x, k);
update(1LL * x + 1LL * dep[v]*k, k, L[v], R[v], );
} else {
sf(v);
printf("%lld\n", query(L[v], dep[v], ));
}
}
}
return ;
}