题面:https://www.lydsy.com/JudgeOnline/problem.php?id=4154

 

 

 

 

 

 

 

 

KD树代替数据结构的主要思路:把限制条件转化到KD树上面的维度来进行计算

题解

用KD树的思路比较简单

 

先把整棵树的dfs序:dfn数组求出来,随便把每个点的深度dep和子树大小siz求出来

把点的坐标视为(dfn[i],dep[i])

修改操作及对dfn[x]<=dfn[i]<=dfn[x]+siz[x]-1 , dep[x]<=dep[i]<=dep[x]+y 的所有i进行区间覆盖颜色z

单点查询就直接把当前点到根的路径上的懒标记下放

然后不到25min就水过去了。。。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gi()
{
	char c;int num=0,flg=1;
	while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
	while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
	return num*flg;
}
#define N 100005
#define lc ch[i][0]
#define rc ch[i][1]
const int mod=1000000007;
const int INF=0x3f3f3f3f;
int fir[N],to[N],nxt[N],cnt;
int siz[N],dep[N],dfn[N],dc;
void adde(int a,int b){to[++cnt]=b;nxt[cnt]=fir[a];fir[a]=cnt;}
void dfs(int u,int ff)
{
	dep[u]=dep[ff]+1;dfn[u]=++dc;siz[u]=1;
	for(int p=fir[u];p;p=nxt[p]){dfs(to[p],u);siz[u]+=siz[to[p]];}
}
int D;
int ch[N][2],fa[N],rt,tot;
int tmp[N];
int a[N][2],mi[N][2],mx[N][2];
int la[N],col[N];
int qmi[2],qmx[2];
inline void pushup(int i)
{
	mi[i][0]=min(min(mi[lc][0],mi[rc][0]),a[i][0]);
	mx[i][0]=max(max(mx[lc][0],mx[rc][0]),a[i][0]);
	mi[i][1]=min(min(mi[lc][1],mi[rc][1]),a[i][1]);
	mx[i][1]=max(max(mx[lc][1],mx[rc][1]),a[i][1]);
}
inline void pushdown(int i)
{
	if(la[i]){
		if(lc)la[lc]=col[lc]=la[i];
		if(rc)la[rc]=col[rc]=la[i];
		la[i]=0;
	}
}
inline bool cmp(const int &x,const int &y){return a[x][D]<a[y][D];}
void build(int &i,int l,int r,int d)
{
	int mid=(l+r)>>1;D=d;
	nth_element(tmp+l,tmp+mid,tmp+r+1,cmp);
	i=tmp[mid];lc=rc=0;
	if(l<mid)build(lc,l,mid-1,d^1);
	if(r>mid)build(rc,mid+1,r,d^1);
	pushup(i);fa[lc]=fa[rc]=i;
}
void insert(int &i,int k)
{
	if(!i)return;
	pushdown(i);
	if(mi[i][0]>qmx[0]||qmi[0]>mx[i][0]||mi[i][1]>qmx[1]||qmi[1]>mx[i][1])return;
	if(qmi[0]<=mi[i][0]&&mx[i][0]<=qmx[0]&&qmi[1]<=mi[i][1]&&mx[i][1]<=qmx[1]){col[i]=la[i]=k;return;}
	if(qmi[0]<=a[i][0]&&a[i][0]<=qmx[0]&&qmi[1]<=a[i][1]&&a[i][1]<=qmx[1])col[i]=k;
	if(lc)insert(lc,k);
	if(rc)insert(rc,k);
}
void pdpath(int i)
{
	if(fa[i])pdpath(fa[i]);
	pushdown(i);
}
int main()
{
	int T,n,m,Q,i,x,y,z,ans;
	T=gi();
	while(T--){
		ans=0;
		memset(fir,0,sizeof(fir));cnt=0;dc=0;
		memset(dep,0,sizeof(dep));
		memset(dfn,0,sizeof(dfn));
		memset(siz,0,sizeof(siz));
		
		memset(fa,0,sizeof(fa));
		memset(ch,0,sizeof(ch));rt=tot=0;
		memset(tmp,0,sizeof(tmp));
		memset(a,0,sizeof(a));
		memset(mi,0,sizeof(mi));
		memset(mx,0,sizeof(mx));
		memset(la,0,sizeof(la));
		mi[0][0]=mi[0][1]=INF;
		mx[0][0]=mx[0][1]=-INF;
		
		n=gi();m=gi();Q=gi();
		for(i=2;i<=n;i++){
			x=gi();
			adde(x,i);
		}
		dfs(1,0);
		for(i=1;i<=n;i++){
			a[i][0]=dfn[i];
			a[i][1]=dep[i];
			tmp[++tot]=i;col[i]=1;
		}
		build(rt,1,tot,0);
		for(i=1;i<=Q;i++){
			x=gi();y=gi();z=gi();
			if(!z){
				pdpath(x);
				ans=(1ll*ans+1ll*col[x]*i)%mod;
			}
			else{
				qmi[0]=dfn[x];qmx[0]=dfn[x]+siz[x]-1;
				qmi[1]=dep[x];qmx[1]=dep[x]+y;
				insert(rt,z);
			}
		}
		printf("%d\n",ans);
	}
}