BZOJ4154 : [Ipsc2015]Generating Synergy
求出dfs序和每个点的深度
将第i个点看成二维点(st[i],d[i])
则修改操作等价于将横坐标在[st[x],en[x]]内,纵坐标在[d[x],d[x]+y]范围内的点的颜色都修改为c
用支持标记下放的k-d树维护即可,时间复杂度$O(n\log n+q\sqrt{n})$。
#include<cstdio> #include<algorithm> #define N 100010 int T,n,c,m,x,y,i,g[N],nxt[N],st[N],en[N],dfn,d[N],id[N],tmp[N],ans,root,cmp_d,x1,y1,x2,y2; inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';} struct node{int d[2],l,r,Max[2],Min[2],tag,col,f;}t[N]; inline bool cmp(node a,node b){return a.d[cmp_d]<b.d[cmp_d];} void dfs(int x){ t[x].tag=x,t[x].d[0]=st[x]=++dfn,t[x].d[1]=d[x]; for(int i=g[x];i;i=nxt[i])d[i]=d[x]+1,dfs(i); en[x]=dfn; } inline void umax(int&a,int b){if(a<b)a=b;} inline void umin(int&a,int b){if(a>b)a=b;} inline void up(int x){ id[t[x].tag]=x,t[x].tag=0,t[x].col=1; if(t[x].l){ umax(t[x].Max[0],t[t[x].l].Max[0]); umin(t[x].Min[0],t[t[x].l].Min[0]); umax(t[x].Max[1],t[t[x].l].Max[1]); umin(t[x].Min[1],t[t[x].l].Min[1]); } if(t[x].r){ umax(t[x].Max[0],t[t[x].r].Max[0]); umin(t[x].Min[0],t[t[x].r].Min[0]); umax(t[x].Max[1],t[t[x].r].Max[1]); umin(t[x].Min[1],t[t[x].r].Min[1]); } } int build(int l,int r,int D,int f){ int mid=(l+r)>>1; cmp_d=D,std::nth_element(t+l+1,t+mid+1,t+r+1,cmp); t[mid].f=f; t[mid].Max[0]=t[mid].Min[0]=t[mid].d[0]; t[mid].Max[1]=t[mid].Min[1]=t[mid].d[1]; if(l!=mid)t[mid].l=build(l,mid-1,!D,mid);else t[mid].l=0; if(r!=mid)t[mid].r=build(mid+1,r,!D,mid);else t[mid].r=0; return up(mid),mid; } inline void tag1(int x,int y){t[x].col=t[x].tag=y;} inline void pb(int x){ if(t[x].tag){ if(t[x].l)tag1(t[x].l,t[x].tag); if(t[x].r)tag1(t[x].r,t[x].tag); t[x].tag=0; } } inline void change(int x){ if(t[x].Max[0]<x1||t[x].Min[0]>x2||t[x].Max[1]<y1||t[x].Min[1]>y2)return; if(t[x].Min[0]>=x1&&t[x].Max[0]<=x2&&t[x].Min[1]>=y1&&t[x].Max[1]<=y2){tag1(x,c);return;} pb(x); if(t[x].d[0]>=x1&&t[x].d[0]<=x2&&t[x].d[1]>=y1&&t[x].d[1]<=y2)t[x].col=c; if(t[x].l)change(t[x].l); if(t[x].r)change(t[x].r); } inline int ask(int x){ int s=0,i=x; while(t[i].f)tmp[++s]=i=t[i].f; while(s)pb(tmp[s--]); return t[x].col; } int main(){ for(read(T);T--;printf("%d\n",ans)){ read(n),read(c),read(m); for(i=1;i<=n;i++)g[i]=0; for(i=2;i<=n;i++)read(x),nxt[i]=g[x],g[x]=i; dfs(1),root=build(1,n,0,0),ans=0; for(i=1;i<=m;i++){ read(x),read(y),read(c); if(c)x1=st[x],x2=en[x],y1=d[x],y2=d[x]+y,change(root); else ans=(1LL*ask(id[x])*i+ans)%1000000007; } } return 0; }