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;

}

  

你可能感兴趣的:(ZOJ)