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

  

时间: 2024-08-06 00:26:54

BZOJ4154 : [Ipsc2015]Generating Synergy的相关文章

【kd-tree】bzoj4154 [Ipsc2015]Generating Synergy

区间修改的kd-tree,打标记,下传. 每次询问的时候,从询问点向上找到根,然后依次下传下来,再回答询问. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 100001 #define KD 2 int n,root,m,q,qp[2][KD],fa[N],val,delta[N]; bool dn; struct Node { int ch[2

BZOJ4154——IPSC2015 Generating Synergy

题意:AC通道 题解: 这题有个十分巧妙的解法. 因为有子树修改,而又不是整棵子树的修改,直接上dfs序是不行的. 考虑它每次修改的只有子节点,而且有距离限制,我们想到这是与点的深度有关的问题. 于是我们把树上的点抽象到二维平面上,横坐标为其dfs序,纵坐标为其深度,这样每次的修改就对应一个区域的染色操作,这东西用kdtree可以随便搞,弄个lazytag就可以了. 一堆调试用的代码,所以看起来很长. #include <bits/stdc++.h> //#include <conio.

【BZOJ4154】[Ipsc2015]Generating Synergy KDtree

[BZOJ4154][Ipsc2015]Generating Synergy Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 Input 第一行一个数T,表示数据组数 接下来每组数据的第一行三个数n,c,q表示结点个数,颜色数和操作数 接下来一行n-1个数描述2..n的父节点 接下来q行每行三个数a,l,c 若c为0,表示询问a的颜色 否则将距离a不超过l的a的子节点染成c Output 设当前是第i个操作,y

BZOJ 4154 [Ipsc2015]Generating Synergy(KD-Tree)

题目链接:BZOJ 4154 [Ipsc2015]Generating Synergy 题意: 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色. 题解: 将dfs序看为x,dep看为y,那么就是一个在二维平面上的操作了. 由于这个平面范围比较大,二维线段树不好开,然后kd-tree搞搞. 1 #include<cstdio> 2 #include<algorithm> 3 #define F(i,a,b) for(int

【bzoj4154】[Ipsc2015]Generating Synergy KD-tree

题目描述 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 输入 第一行一个数T,表示数据组数 接下来每组数据的第一行三个数n,c,q表示结点个数,颜色数和操作数 接下来一行n-1个数描述2..n的父节点 接下来q行每行三个数a,l,c 若c为0,表示询问a的颜色 否则将距离a不超过l的a的子节点染成c 输出 设当前是第i个操作,y_i为本次询问的答案(若本次操作是一个修改则y_i为0),令z_i=i*y_i,请输出z_1+z_2+..

[Ipsc2015]Generating Synergy

传送门 这个题有点意思啊,我可能kd-tree的板子写的有点问题,查询的时候就是要暴力查左右儿子,记录的最大最小值毫无作用,不清楚为什么. 这个题也算是比较简单的啦,由于是子树操作,只要想到按dfs序建树就没有什么问题了 其他的也就是一个区间覆盖,没有什么难度 代码: #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; v

Maven在[INFO] Generating project in Interactive mode卡住的问题解决

我的环境: Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00) Maven home: /usr/local/maven3 Java version: 1.8.0_111, vendor: Oracle Corporation Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Ho

Maven &quot;Generating project in Batch mode&quot;问题的解决 (转)

在maven的五分钟入门里面,有这样一个命令: mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false 这句话的命令是创建一个默认的项目,但我在执行这个命令时,命令行会停在 [INFO] Generating project in Batch mode 这句话会停很久

转:Generating PDFs from Web Pages on the Fly with jsPDF

The Portable Document Format has been one the major innovations in the fields of desktop publishing and office automations. It’s widely used in web publishing too, but unfortunately very often in wrong ways – like using it to replace contents that sh