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;
}

  

posted @ 2015-06-22 23:38  Claris  阅读(925)  评论(0编辑  收藏  举报