PS:这个题目改了很久的bug但是就是没有改出来,最后将uvk三个局部变量变成全局变量居然很神奇的过了,表示不明白,如果有大佬知道为什么,欢迎留言。
题目链接点击打开链接
题意很简单,就是更新一个结点v的值(+x),然后更新其所有子孙vv的值(+x-d*k)
d=d[vv]-d[v];
首先跑一个dfs,将树转为一维线性的,得到所有点的子孙区间L-R;
这个题目的结点存值思路很巧妙,当更新点的时候,更新该点L-R区间的所有点,其值更新为 原值+x+k*deep[u];其lazy标记用来储存当前点的k值之和。
这样在我们求单点值的时候,只需要将其值-所有k之和*当前点深度即可。
写写例子,把式子带进去就会很容易理解这个思路的正确性
#include <iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>
#include<map>
#include<string>
#include<cmath>
#include<queue>
#include<cmath>
#include<vector>
using namespace std;
const long long mod=1e9+7;
const int maxn=3e5+100;
long long tree[maxn*4];
long long add[maxn*4];
vector<long long> s[maxn];
int L[maxn];
int R[maxn];
int v;
long long x,k;
int cnt;
long long de[maxn];
void dfs(int ro)
{
L[ro]=++cnt;
for(int i=0; i<s[ro].size(); i++)
{
int to=s[ro][i];
de[to]=de[ro]+1;
dfs(to);
}
R[ro]=cnt;
}
void build(int root,int l,int r)
{
tree[root]=0;
add[root]=0;
if(l==r)
return ;
else
{
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
}
}
void pushdown(int root)
{
if(add[root])
{
add[root*2]=(add[root*2]+add[root])%mod;
add[root*2+1]=(add[root*2+1]+add[root])%mod;
add[root]=0;
}
if(tree[root])
{
tree[root*2]=(tree[root]+tree[root*2])%mod;
tree[root*2+1]=(tree[root]+tree[root*2+1])%mod;
tree[root]=0;//注意要清空,否则下次更新时还会重复加当前结果
}
}
void update(int root,int l,int r,int ul,int ur)
{
if(ul<=l&&ur>=r)
{
tree[root]=(tree[root]+de[v]*k%mod+x)%mod;
add[root]=(add[root]+k)%mod;
return ;
}
pushdown(root);
int mid=(l+r)/2;
if(ul<=mid)
update(root*2,l,mid,ul,ur);
if(ur>mid)
update(root*2+1,mid+1,r,ul,ur);
}
void query(int root,int l,int r,int x)
{
if(l==r)
{
printf("%lld\n",((tree[root]-de[v]*add[root]%mod)%mod+mod)%mod);
return ;
}
pushdown(root);
int mid=(l+r)/2;
if(x<=mid)
query(root*2,l,mid,x);
else
query(root*2+1,mid+1,r,x);
}
int main()
{
int T;
int n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
s[i].clear();
for(int i=2; i<=n; i++)
{
int x;
scanf("%d",&x);
s[x].push_back(i);
}
cnt=0;
dfs(1);
build(1,1,cnt);
int m;
scanf("%d",&m);
while(m--)
{
int a;
scanf("%d",&a);
if(a==1)
{
// int u;
// long long v,k;
scanf("%d%lld%lld",&v,&x,&k);
update(1,1,cnt,L[v],R[v]);
}
else
{
// int u;
scanf("%d",&v);
query(1,1,cnt,L[v]);
}
}
}
return 0;
}
/*
1
7
1 1 2 3 1 3
7
1 1 2 2
2 3
2 5
1 3 2 1
2 3
2 7
*/
》》》》》
局部变量到底错在了哪》》????