按照dfs序建K-D树,用deepi表示i在原树中的深度,想想成二维平面中的点,第一维是dfs序,第二维是深度,则对于一个染色操作其实就是在二维平面内的区域
sb错误get。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 1e9
#define N 100005
#define ll long long
#define mod 1000000007
using namespace std;
int n,c,q,a,l,x1,x2,y1,y2,D,dfn,cnt,ans,root;
struct node
{
int d[2],mn[2],mx[2];
int tag,col,fa;
};
node tree[N];
int ls[N],rs[N];
int head[N],deep[N],next[N],list[N],in[N],out[N],id[N],stack[N];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
}
inline bool operator<(node a,node b)
{
return a.d[D]<b.d[D];
}
void dfs(int x)
{
in[x]=++dfn;
tree[x].d[0]=dfn; tree[x].d[1]=deep[x]; tree[x].tag=x;
for (int i=head[x];i;i=next[i])
{
deep[list[i]]=deep[x]+1;
dfs(list[i]);
}
out[x]=dfn;
}
inline void pushup(int k)
{
id[tree[k].tag]=k; tree[k].tag=0; tree[k].col=1;
for (int i=0;i<=1;i++)
{
tree[k].mn[i]=min(tree[k].d[i],min(tree[ls[k]].mn[i],tree[rs[k]].mn[i]));
tree[k].mx[i]=max(tree[k].d[i],max(tree[ls[k]].mx[i],tree[rs[k]].mx[i]));
}
}
void build(int &k,int l,int r,int dir,int f)
{
int mid=l+r>>1; k=mid; D=dir;
nth_element(tree+l,tree+mid,tree+r+1);
tree[k].fa=f; //要写在上一句下面!
if (l<mid) build(ls[k],l,mid-1,dir^1,k); else ls[k]=0;
if (r>mid) build(rs[k],mid+1,r,dir^1,k); else rs[k]=0;
pushup(k);
}
inline void pushdown(int k)
{
if (tree[k].tag)
{
if (ls[k]) tree[ls[k]].tag=tree[ls[k]].col=tree[k].tag;
if (rs[k]) tree[rs[k]].tag=tree[rs[k]].col=tree[k].tag;
tree[k].tag=0;
}
}
void change(int k)
{
if (tree[k].mn[0]>x2||tree[k].mx[0]<x1||tree[k].mn[1]>y2||tree[k].mx[1]<y1) return;
if (tree[k].mn[0]>=x1&&tree[k].mx[0]<=x2&&tree[k].mx[1]<=y2&&tree[k].mn[1]>=y1)
{
tree[k].tag=tree[k].col=c;
return;
}
pushdown(k);
if (tree[k].d[0]>=x1&&tree[k].d[0]<=x2&&tree[k].d[1]>=y1&&tree[k].d[1]<=y2) tree[k].col=c;
if (ls[k]) change(ls[k]);
if (rs[k]) change(rs[k]);
}
inline int query(int x)
{
int now=x,top=0;
while (tree[now].fa) stack[++top]=now=tree[now].fa;
while (top) pushdown(stack[top--]);
return tree[x].col;
}
int main()
{
// freopen("g.in","r",stdin);
// freopen("g1.out","w",stdout);
for (int i=0;i<=1;i++)
tree[0].mn[i]=inf,tree[0].mx[i]=-inf;
int testcase=read();
while (testcase--)
{
n=read(),c=read(),q=read(); cnt=0; ans=0;
memset(head,0,sizeof(head));
for (int i=2;i<=n;i++)
insert(read(),i);
dfs(1);
build(root,1,n,0,0);
// for (int i=1;i<=n;i++)
// printf("%d %d %d %d\n",tree[i].mx[0],tree[i].mx[1],tree[i].mn[0],tree[i].mn[1]);
// for (int i=1;i<=n;i++)
// printf("%d ",tree[i].fa);
for (int i=1;i<=q;i++)
{
a=read(); l=read(); c=read();
if (!c) ans=(1ll*query(id[a])*i+ans)%mod;
else
{
x1=in[a]; x2=out[a]; y1=deep[a]; y2=deep[a]+l;
change(root);
}
}
cout << ans << endl;
}
return 0;
}
976

被折叠的 条评论
为什么被折叠?



