NKOJ 4345 (Ipsc2015)Generating Synergy (DFS序+kd树)
来源:互联网 发布:java预约系统源代码 编辑:程序博客网 时间:2024/05/19 23:56
P4345[Ipsc2015]Generating Synergy
问题描述
给定一棵以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+…+z_q模10^9+7
样例输入
1
4 3 7
1 2 2
3 0 0
2 1 3
3 0 0
1 0 2
2 0 0
4 1 1
4 0 0
样例输出
32
提示
第1,3,5,7的询问的答案分别为1,3,3,1,所以答案为 1*1+2*0+3*3+4*0+5*3+6*0+7*1=32.
数据范围:
对于100%的数据T<=6,n,m,c<=10^5,
1<=a<=n,0<=l<=n,0<=c<=c
首先求出这棵树的DFS序和每个节点的深度,那么将DFS序的
另外,也可以用树套树维护,但显然不如kd树好写。
代码:
#include<stdio.h>#include<iostream>#include<algorithm>#include<cstring>#define N 222222#define ll long longusing namespace std;int rt,D,T,n,c,q,x1,x2,y1,y2;int L[N],R[N],dep[N],VT,mod=1e9+7;int LA[N],NE[N],EN[N],TOT;struct node{ int d[2],x[2],y[2],son[2],v,lazy; bool operator<(const node &b)const {return d[D]<b.d[D];}}kdt[N];void PD(int p){ int ls=kdt[p].son[0],rs=kdt[p].son[1]; kdt[ls].v=kdt[rs].v=kdt[p].lazy; kdt[ls].lazy=kdt[rs].lazy=kdt[p].lazy; kdt[p].lazy=0;}void MT(int p,int s){ kdt[p].x[0]=min(kdt[p].x[0],kdt[s].x[0]); kdt[p].x[1]=max(kdt[p].x[1],kdt[s].x[1]); kdt[p].y[0]=min(kdt[p].y[0],kdt[s].y[0]); kdt[p].y[1]=max(kdt[p].y[1],kdt[s].y[1]);}int BT(int l,int r,int d){ D=d;int o=l+r>>1; kdt[o].v=1; kdt[o].x[0]=kdt[o].x[1]=kdt[o].d[0]; kdt[o].y[0]=kdt[o].y[1]=kdt[o].d[1]; if(l<o)kdt[o].son[0]=BT(l,o-1,d^1),MT(o,kdt[o].son[0]); if(o<r)kdt[o].son[1]=BT(o+1,r,d^1),MT(o,kdt[o].son[1]); return o;}void ADD(int x,int y){ TOT++; EN[TOT]=y; NE[TOT]=LA[x]; LA[x]=TOT;}void DFS(int x,int f){ L[x]=++VT;dep[x]=dep[f]+1; for(int i=LA[x];i;i=NE[i])DFS(EN[i],x); R[x]=VT;}int GA(int p){ if(kdt[p].lazy)PD(p); if(kdt[p].d[0]==x1&&kdt[p].d[1]==y1)return kdt[p].v; int s=0,ls=kdt[p].son[0],rs=kdt[p].son[1]; if(kdt[ls].x[0]<=x1&&kdt[ls].x[1]>=x1&&kdt[ls].y[0]<=y1&&kdt[ls].y[1]>=y1)s+=GA(ls); if(kdt[rs].x[0]<=x1&&kdt[rs].x[1]>=x1&&kdt[rs].y[0]<=y1&&kdt[rs].y[1]>=y1)s+=GA(rs); return s;}void CHA(int p,int k){ if(kdt[p].lazy)PD(p); if(kdt[p].d[0]<=x2&kdt[p].d[0]>=x1&&kdt[p].d[1]<=y2&&kdt[p].d[0]>=y1)kdt[p].v=k; if(kdt[p].x[0]>x2||kdt[p].x[1]<x1||kdt[p].y[0]>y2||kdt[p].y[1]<y1)return; if(kdt[p].x[1]<=x2&&kdt[p].x[0]>=x1&&kdt[p].y[1]<=y2&&kdt[p].y[0]>=y1){kdt[p].v=kdt[p].lazy=k;return;} CHA(kdt[p].son[0],k);CHA(kdt[p].son[1],k);}int main(){ int i,k,x,y;ll ans; scanf("%d",&T); while(T--) { TOT=VT=ans=0; memset(kdt,0,sizeof(kdt)); memset(LA,0,sizeof(LA)); scanf("%d%d%d",&n,&c,&q); for(i=2;i<=n;i++)scanf("%d",&x),ADD(x,i); DFS(1,0); for(i=1;i<=n;i++)kdt[i].d[0]=L[i],kdt[i].d[1]=dep[i]; rt=BT(1,n,0); for(i=1;i<=q;i++) { scanf("%d%d%d",&x,&y,&k); if(k==0) { x1=L[x];y1=dep[x]; ans=(ans+1ll*GA(rt)*i)%mod; } else { x1=L[x];x2=R[x]; y1=dep[x];y2=dep[x]+y; CHA(rt,k); } } printf("%lld\n",ans); }}
阅读全文
0 0
- NKOJ 4345 (Ipsc2015)Generating Synergy (DFS序+kd树)
- 【BZOJ】4154: [Ipsc2015]Generating Synergy【KD树】
- bzoj 4154: [Ipsc2015]Generating Synergy (KD-tree)
- 【IPSC2015】【BZOJ4154】Generating Synergy
- [bzoj4154][Ipsc2015]Generating Synergy
- BZOJ4154 [Ipsc2015]Generating Synergy
- BZOJ4154: [Ipsc2015]Generating Synergy
- BZOJ4154——IPSC2015 Generating Synergy
- 4154: [Ipsc2015]Generating Synergy K-D tree
- bzoj 4154: [Ipsc2015]Generating Synergy KDtree
- [Ipsc2015]Generating Synergy K-D tree
- BZOJ 4154(Generating Synergy-kd-tree代替树套树)
- BZOJ4154:Generating Synergy (KDtree)
- HYSBZ4154-Generating Synergy
- NKOJ 3489 避难向导(LCA+倍增+DFS/DP)
- 【38.05%】【BZOJ 4154】Generating Synergy
- 关于KD树(未完)
- NKOJ 4254 区间MEX (线段树)
- select函数与stdio混用的不良后果
- Flume和Kafka的整合完成实时数据采集
- ArrayList至SharedPreferences
- dede:if DEDE模板中使用php和if判断语句的技巧
- Springboot实现quartz定时
- NKOJ 4345 (Ipsc2015)Generating Synergy (DFS序+kd树)
- 嵌入式软件工程师经典面试题
- yii2的url
- POJ 2635.The Embarrassed Cryptographer
- python学习_6
- Robot Framework 源代码阅读笔记 之二
- 东莞虎门一直都很不错滓
- Java中折半查找
- dede 模板 if dedecms模板中运用dede标签时使用php和if判断语句的方法