用dfs序可以维护出所有子节点
对于更新,我们将更新变为
deep[i]k−deep[j]k
d
e
e
p
[
i
]
k
−
d
e
e
p
[
j
]
k
,
deep[j]k
d
e
e
p
[
j
]
k
就是当前自己的深度,是可以直接计算的,那么对于
deep[i]k
d
e
e
p
[
i
]
k
,就是父亲节点的深度,另外别忘了还有
x
x
,所以我们对于父亲节点的所有儿子首先更新,
lazy
l
a
z
y
标记下放
k
k
,就能做到了
然后这题把 x、v、k x 、 v 、 k 改成全局变量才能过??这是什么问题
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <map>
#include <sstream>
#define LL long long
#define INF 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-8
const int maxn = 300000 + 5;
using namespace std;
vector<int> vec[maxn];
int idx;
int ver[maxn];
int L[maxn];
int R[maxn];
int n;
int deep[maxn];
LL lazy[maxn*4];
LL a[maxn*4];
int v;
LL x,k;
int op;
void dfs(int cur, int fa, int step){
L[cur] = ++idx;
ver[idx] = cur;
deep[idx] = step;
for(int i=0; i<vec[cur].size(); i++){
int v = vec[cur][i];
if(v != fa){
dfs(v,cur,step+1);
}
}
R[cur] = idx;
}
void pushdown(int o){
if(lazy[o]){
lazy[o*2] += lazy[o];
lazy[o*2] %= mod;
lazy[o*2+1] += lazy[o];
lazy[o*2+1] %= mod;
lazy[o] = 0;
}
if(a[o]){
a[o*2] += a[o];
a[o*2] %= mod;
a[o*2+1] += a[o];
a[o*2+1] %= mod;
a[o] = 0;
}
}
void build(int l, int r, int o) {
if(l == r){
a[o] = 0;
return ;
}
int m = (l + r) / 2;
build(l,m,o*2);
build(m+1,r,o*2+1);
}
LL query(int l, int r, int o, int v){
if(l == r){
return(a[o] + deep[l]*lazy[o] % mod + mod) % mod;
}
pushdown(o);
int m = (l + r) / 2;
if(m >= v)
return query(l,m,o*2,v);
else
return query(m+1,r,o*2+1,v);
}
void update(int l, int r, int o, int ql, int qr, LL c, LL k){
if(ql <= l && qr >= r){
lazy[o] = ((lazy[o] + k) % mod + mod) % mod;
a[o] = ((a[o] + c) % mod + mod) % mod ;
return ;
}
pushdown(o);
int m = (l + r) / 2;
if(m >= ql) update(l,m,o*2,ql,qr,c,k);
if(m < qr) update(m+1,r,o*2+1,ql,qr,c,k);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
idx = 0;
for(int i=0; i<maxn; i++)
vec[i].clear();
memset(deep, 0, sizeof(deep));
memset(lazy, 0, sizeof(lazy));
memset(a, 0, sizeof(a));
scanf("%d",&n);
for(int i=2; i<=n; i++){
int x;
scanf("%d",&x);
vec[x].push_back(i);
}
dfs(1,-1,1);
build(1,n,1);
int q;
scanf("%d",&q);
while(q--){
scanf("%d",&op);
if(op == 1){
scanf("%d%lld%lld",&v,&x,&k);
update(1, n, 1, L[v], R[v], deep[L[v]]*k + x, -k);
}
else{
scanf("%d",&v);
printf("%lld\n",(query(1,n,1,L[v]) % mod + mod) % mod);
}
}
}
return 0;
}