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$:又把边 ...
随机推荐
- 3.Java和hadoop的安装
先创建目录 [hadoop@node1 opt]$ cd /opt [hadoop@node1 opt]$ sudo mkdir /opt/softwares [hadoop@node1 opt]$ ...
- [Python3] 034 函数式编程 匿名函数
目录 函数式编程 Functional Programming 1. 简介 2. 函数 3. 匿名函数 3.1 lambda 表达式也称"匿名函数" 3.2 lambda 表达式的 ...
- PTA(Basic Level)1016.部分A+B
正整数 A 的"*D**A(为 1 位整数)部分"定义为由 A* 中所有 *D**A* 组成的新整数 PA.例如:给定 A=3862767,DA=6,则 A 的"6 部分 ...
- PTA(Basic Level)1026.程序运行时间
要获得一个 C 语言程序的运行时间,常用的方法是调用头文件 time.h,其中提供了 clock() 函数,可以捕捉从程序开始运行到 clock() 被调用时所耗费的时间.这个时间单位是 clock ...
- CentOS7安装SVN1.9.12
检查卸载原有的svn svn --version # 检查是否原有svn yum remove svn # 卸载原有svn 安装依赖: apr-1.6.5 mkdir /opt/software/sv ...
- Go语言流程控制中的break,continue和goto(七)
break(跳出循环) break用于跳出整个循环,如下: func main() { ;i<;i++{ { break } fmt.Println(i) } } // 0 1 2 3 代码里只 ...
- 手写Spring MVC
闲及无聊 又打开了CSDN开始看一看有什么先进的可以学习的相关帖子,这时看到了一位大神写的简历装X必备,手写Spring MVC. 我想这个东西还是有一点意思的 就拜读了一下大佬的博客 通读了一遍相关 ...
- DLL的创建与使用
一.动态链接库(DLL) 动态链接库提供了一种方法,使进程可以调用不属于其执行代码的函数.函数的可执行代码位于一个.dll文件中,该文件包含一个或多个已被编译.链接并使用它们的进程分开存储的函数. 优 ...
- C/C++的几个输入流
C: 1.scanf( ) 存在于<stdio.h>(C++为<cstdio>)中,根据stdin读取数据并根据参数格式进行赋值,以第一个非空格字符(空格字符如:空格,制符表, ...
- jQuery选择器引入
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...