BZOJ 4154: [Ipsc2015]Generating Synergy KDtree+dfs序
多组数据真tm恶心~
把 $dfs$序和深度分别看作横纵坐标,然后用 $KDtree$ 数点就可以了~
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 300005
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int d;
struct Node {
int ch[2], tag, col, minv[2], maxv[2], p[2];
}t[N];
int isout(int x1,int y1,int x2,int y2,int x) {
return (x1>t[x].maxv[0]||x2<t[x].minv[0]||y1>t[x].maxv[1]||y2<t[x].minv[1]);
}
int isin(int x1,int y1,int x2,int y2,int x) {
return (t[x].minv[0]>=x1&&t[x].maxv[0]<=x2&&t[x].minv[1]>=y1&&t[x].maxv[1]<=y2);
}
bool cmp(Node a,Node b) {
return a.p[d]==b.p[d]?a.p[d^1]<b.p[d^1]:a.p[d]<b.p[d];
}
void pushup(int x,int y) {
for(int i=0;i<2;++i)
t[x].minv[i]=min(t[x].minv[i],t[y].minv[i]),t[x].maxv[i]=max(t[x].maxv[i],t[y].maxv[i]);
}
void mark(int x,int c) {
t[x].col=t[x].tag=c;
}
void pushdown(int x) {
if(t[x].tag!=-1) {
if(t[x].ch[0]) mark(t[x].ch[0],t[x].tag);
if(t[x].ch[1]) mark(t[x].ch[1],t[x].tag);
t[x].tag=-1;
}
}
int build(int l,int r,int o) {
int mid=(l+r)>>1,i;
d=o, nth_element(t+l,t+mid,t+1+r,cmp);
t[mid].minv[0]=t[mid].maxv[0]=t[mid].p[0];
t[mid].minv[1]=t[mid].maxv[1]=t[mid].p[1];
t[mid].col=1, t[mid].tag=-1;
if(mid>l) t[mid].ch[0]=build(l,mid-1,o^1), pushup(mid, t[mid].ch[0]);
if(r>mid) t[mid].ch[1]=build(mid+1,r,o^1), pushup(mid, t[mid].ch[1]);
return mid;
}
void update(int x1,int y1,int x2,int y2,int c,int x) {
if(!x||isout(x1,y1,x2,y2,x)) return;
if(isin(x1,y1,x2,y2,x)) {
mark(x,c);
return;
}
if(t[x].p[0]>=x1&&t[x].p[0]<=x2&&t[x].p[1]>=y1&&t[x].p[1]<=y2) t[x].col=c;
pushdown(x);
if(t[x].ch[0])
update(x1,y1,x2,y2,c,t[x].ch[0]);
if(t[x].ch[1])
update(x1,y1,x2,y2,c,t[x].ch[1]);
}
int query(int x1,int y1,int x) {
if(!x||isout(x1,y1,x1,y1,x)) return -1;
if(t[x].p[0]==x1&&t[x].p[1]==y1) return t[x].col;
pushdown(x);
return max(query(x1,y1,t[x].ch[0]), query(x1,y1,t[x].ch[1]));
}
int n,edges,tim,fa[N],hd[N],nex[N],to[N],dfn[N],size[N],dep[N];
void addedge(int u,int v) {
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void dfs(int u) {
dfn[u]=++tim,size[u]=1;
for(int i=hd[u];i;i=nex[i])
dep[to[i]]=dep[u]+1,dfs(to[i]),size[u]+=size[to[i]];
}
void solve() {
edges=0;
memset(hd,0,sizeof(hd));
int i,j;
int Q,C;
scanf("%d%d%d",&n,&C,&Q);
for(i=2;i<=n;++i) scanf("%d",&fa[i]), addedge(fa[i],i);
dfs(1);
for(i=1;i<=n;++i) t[i].p[0]=dfn[i],t[i].p[1]=dep[i],t[i].ch[0]=t[i].ch[1]=0, t[i].tag=-1;
int root=build(1,n,0);
long long lastans=0;
for(i=1;i<=Q;++i) {
int a,l,c;
scanf("%d%d%d",&a,&l,&c);
if(c==0) lastans=(lastans+(long long)i*query(dfn[a], dep[a], root))%1000000007;
else {
update(dfn[a],dep[a],dfn[a]+size[a]-1,dep[a]+l,c,root);
}
}
printf("%lld\n",lastans);
}
int main() {
int T;
// setIO("input");
scanf("%d",&T);
while(T--) solve();
return 0;
}
BZOJ 4154: [Ipsc2015]Generating Synergy KDtree+dfs序的更多相关文章
- 【BZOJ4154】[Ipsc2015]Generating Synergy KDtree
[BZOJ4154][Ipsc2015]Generating Synergy Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问 ...
- 【bzoj4154】[Ipsc2015]Generating Synergy KD-tree
题目描述 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 输入 第一行一个数T,表示数据组数 接下来每组数据的第一行三个数n,c,q表示结 ...
- 4154: [Ipsc2015]Generating Synergy
Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 区间修改单点查询kdtree #include<iostre ...
- BZOJ 4154 kd-tree dfs序 + 二维空间的区间(矩阵)更新单点查找
一开始没思路 感觉像是一个树形dp 然而不会 然后看了一眼题解就明白了 一个点的子树 用dfs序表示肯定是一个连续的区间 并且由于有子树的距离限制 可以转化为一个深度的区间 于是每个点都会有一个在二维 ...
- 【bzoj 4154】[Ipsc2015]Generating Synergy
题目 大概已经掌握熟练码出\(kdt\)的技能了 发现距离子树根节点\(x\)不超过\(l\)的点可以用两种方式来限制,首先\(dfs\)序在\([dfn_x,dfn_x+sum_x)\)中,深度自然 ...
- BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...
- BZOJ4154: [Ipsc2015]Generating Synergy
Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 Input 第一行一个数T,表示数据组数 接下来每组数据的第一 ...
- bzoj 2819 Nim(BIT,dfs序,LCA)
2819: Nim Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1596 Solved: 597[Submit][Status][Discuss] ...
- BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]
传送门 题意:查询树上根节点值*子树中权值和$\le m$的最大数量 最大值是多少 求$DFS$序,然后变成区间中和$\le m$最多有几个元素,建主席树,然后权值线段树上二分就行了 $WA$:又把边 ...
随机推荐
- @Transient注解的使用(不被序列化和作为临时变量存储)
转自:https://blog.csdn.net/sinat_29581293/article/details/51810805 java 的transient关键字的作用是需要实现Serilizab ...
- [Python3] 037 函数式编程 装饰器
目录 函数式编程 之 装饰器 Decrator 1. 引子 2. 简介 3. 使用 函数式编程 之 装饰器 Decrator 1. 引子 >>> def func(): ... pr ...
- (public丶private丶protected) 的理解
public(公有):公有的类成员可以在任何地方被访问. protected(受保护):受保护的类成员则可以被其自身以及其子类和父类访问. private(私有):私有的类成员则只能被其定义所在的类访 ...
- 2019.07.05 纪中_B
今日膜拜:czj大佬orz%%% 2019.07.05[NOIP提高组]模拟 B 组 今天做题的时候大概能判断出题人的考点,可是就是没学过...特别痛苦 T0:栈的定义,模拟就好了T1:感觉像是找规律 ...
- # Tallest Cows(差分)
Tallest Cows(差分) n头牛,给出最高牛的位置和身高,其他牛身高未知,给出m对相对关系,表示可以相互看见当且仅当他们中间的牛都比他们矮.求每头牛身高最大值是多少. 差分数组的性质:前缀和为 ...
- nohup重定向到其它的日志文件
如果使用nohup命令提交作业,那么在缺省情况下该作业的所有输出都被重定向到一个名为nohup.out的文件中,除非另外指定了输出文件: nohup command > myout.file 2 ...
- Redis5版本集群搭建
一.简介 1.1 Redis是什么 Redis是一个开源的,使用ANSI C 编写,高性能的Key-Value的NoSQL数据库. 1.2 Redis特点 (1)基于内存 (2)可持久化数据 (3)具 ...
- 为什么日本编程语言ruby没前途
ruby是日本的编程语言,不像日本生鱼片一样受人喜欢 日本 Ruby的性能不如.NET或Java 你又是对的!另外,Ruby比Erlang,Lua,C ++等慢,但你不使用Erlang或C ++? W ...
- python 3.8 新特性
董伟明技术博客 安装 python 3.8 环境 , 在此刻 似乎 anaconda 都还不支持 3.8 ,所以直接下载源码进行编译安装 环境: centos7.5 版本:python3.8 1.依赖 ...
- exits 和no exits
exists : 强调的是是否返回结果集,不要求知道返回什么, 比如: select name from student where sex = 'm' and mark exists(select ...