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$:又把边 ...
随机推荐
- ThreadPoolExecutor的重要参数
一.ThreadPoolExecutor的重要参数 1.corePoolSize:核心线程数 * 核心线程会一直存活,及时没有任务需要执行 * 当线程数小于核心线程数时 ...
- CSUST 2012 一个顶俩 (本校OJ题)(思维+树链剖分)
(点击这里查看原题,不保证可以进去....外网可能比较卡) Description A:一心一意 B:一个顶俩 最近QQ更新后那个成语接龙好像挺火的?但我只知道图论里一条边是一个顶俩个点的emm. 如 ...
- 从入门到自闭之Python高阶函数
高阶函数:内部帮忙做了一个for循环 filter:筛选过滤 语法: filter(function,iterable) function: 1.指定过滤规则(函数的内存地址) 2.用来筛选的函数,在 ...
- python-day38(正式学习)
目录 线程 线程开启的两种方式 1 2 子线程和子进程的创建速度 子线程共享资源 线程的join方法 守护线程 线程其他用法 线程 线程开启的两种方式 1 from threading import ...
- Django基础之视图(views)层、模板层
目录 Django基础之视图(views)层.模板层 JsonResponse 向前端返回一个json格式字符串的两种方式 重写Django中的json的某个方法 form表单上传文件 FBV与CBV ...
- sql server row_number分页
row_number分页 SELECT TOP 10* --pageSize =10FROM ( SELECT *, row_number () OVER (ORDER BY a.bsqID ...
- vue运行碰到的问题
Expected indentation of 0 spaces but found 2 解决方案: 文件中加入"indent": ["off", 2]就可以了 ...
- Charles学习(二)之使用Map local代理本地静态资源以及配置网页代理在Mac浏览器上调试移动端
前言 我们在开发的过程肯定是一边写代码,一边查看自己的代码写的是否存在问题,那么问题来了,有两种情况 情况一:我们可以本地起服务,那么我们就可以在本地检查自己的代码,查看运行结果 情况二:本地无法起服 ...
- @RequestMapping-标准映射和Ant风格的映射
4.@RequestMapping 如果value不以“/”开头,SpringMVC会自动添加“/” 4.1.@RequestMapping映射 4.1.1.标准URL映射 4.1.2.Ant风格的U ...
- 从命令行运行postman脚本
为什么要在命令行中运行 可以在无UI界面的服务器上运行 可以在持续集成系统上运行 运行准备 导出collection 安装nodejs和npm(或cnpm) 安装Newman 运行及生成测试报告支持4 ...