多组数据真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序的更多相关文章

  1. 【BZOJ4154】[Ipsc2015]Generating Synergy KDtree

    [BZOJ4154][Ipsc2015]Generating Synergy Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问 ...

  2. 【bzoj4154】[Ipsc2015]Generating Synergy KD-tree

    题目描述 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 输入 第一行一个数T,表示数据组数 接下来每组数据的第一行三个数n,c,q表示结 ...

  3. 4154: [Ipsc2015]Generating Synergy

    Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 区间修改单点查询kdtree #include<iostre ...

  4. BZOJ 4154 kd-tree dfs序 + 二维空间的区间(矩阵)更新单点查找

    一开始没思路 感觉像是一个树形dp 然而不会 然后看了一眼题解就明白了 一个点的子树 用dfs序表示肯定是一个连续的区间 并且由于有子树的距离限制 可以转化为一个深度的区间 于是每个点都会有一个在二维 ...

  5. 【bzoj 4154】[Ipsc2015]Generating Synergy

    题目 大概已经掌握熟练码出\(kdt\)的技能了 发现距离子树根节点\(x\)不超过\(l\)的点可以用两种方式来限制,首先\(dfs\)序在\([dfn_x,dfn_x+sum_x)\)中,深度自然 ...

  6. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  7. BZOJ4154: [Ipsc2015]Generating Synergy

    Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色   Input 第一行一个数T,表示数据组数 接下来每组数据的第一 ...

  8. bzoj 2819 Nim(BIT,dfs序,LCA)

    2819: Nim Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1596  Solved: 597[Submit][Status][Discuss] ...

  9. BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]

    传送门 题意:查询树上根节点值*子树中权值和$\le m$的最大数量 最大值是多少 求$DFS$序,然后变成区间中和$\le m$最多有几个元素,建主席树,然后权值线段树上二分就行了 $WA$:又把边 ...

随机推荐

  1. Eclipse中格式化代码

    Eclipse中格式化代码快捷键Ctrl+Shift+F失效的解决办法 格式化代码的时候,右键 --> Source --> Format 能够起效,但 Ctrl+Shift+F不好使. ...

  2. 阿里云服务器挖矿脚本bioset攻击解决

    1.问题出现 一大早刚起床,阿里云就给我发了一条短信,提醒我服务器出现紧急安全事件:挖矿程序 阿里云“贴心”地提供了解决方法,不过需要购买企业版的安全服务,本着能自己动手就不花钱原则自己搞了起来 于是 ...

  3. mybatis 基础(二) xml文件中的其他知识点

    mybatis xml文件中一些标签的使用 此标签主要用作 配置 "别名" 如果实体类与数据库中字段名在不区分大小写的情况下相同的话, 那就不需要配置resultMap,因为mys ...

  4. js判断设备,跳转app应用、android市场或者AppStore

    js移动设备判断方法大全 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" > ...

  5. 使用.NET Core创建Windows服务(一) - 使用官方推荐方式

    原文:使用.NET Core创建Windows服务(一) - 使用官方推荐方式 原文:Creating Windows Services In .NET Core – Part 1 – The &qu ...

  6. VS Code 配置碰到的问题

    VS Code 呈现缩进参考线以及语法高亮改变 找到 首选项——>设置→搜索renderIntentGuides→将此选项改为true(默认为false),就可以了.

  7. 编写 Bash 补全脚本

    编写 Bash 补全脚本   对于Linuxer来说,自动补全是再熟悉不过的一个功能了.当你在命令行敲下部分的命令时,肯定会本能地按下Tab键补全完整的命令,当然除了命令补全之外,还有文件名补全. B ...

  8. Woobuntu

    Wooyun + Ubuntu = Woobuntu Woobuntu是基于Ubuntu系统的一款安全研究环境配置工具,可以自动安装并配置众多的安全工具与依赖环境,此外还针对中国用户的习惯进行了一些优 ...

  9. strings、strconv:让你高效的处理字符串

    strings包 strings.HasPrefix(s, prefix string) bool 判断字符串s是否以prefix开头.类似于python中的startswith. package m ...

  10. Linux添加虚拟网卡的多种方法

    Linux添加虚拟网卡的多种方法有时候,一台服务器需要设置多个ip,但又不想添加多块网卡,那就需要设置虚拟网卡.这里介绍几种方式在linux服务器上添加虚拟网卡. 我们向eth0中添加一块虚拟网卡: ...