题意

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

分析

我们以dfs序为横坐标,深度为纵坐标,建kd树。我们每次更新,都是在kd树中更新一个矩形,横坐标为[st[a],en[a]],纵坐标[depth[a],depth[a]+l]。那么就相当于线段树的区间更新,我们需要给它打个标记。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream> using namespace std;
typedef long long LL;
const int maxn=1e5+;
const int INF=;
const int mod=1e9+; int n,q,c,sz,T;
int head[maxn],Next[*maxn],to[*maxn];
int cnt;
int order[maxn],indx[maxn],st[maxn],en[maxn],depth[maxn];
struct kdNode{
int x[],mnn[],mxn[];
int lc,rc,u;
int val,tag;
}p[maxn],x;
int cmpNo,root;
int cmp(kdNode a,kdNode b){
return a.x[cmpNo]<b.x[cmpNo];
}
void pushdown(int o){
if(p[o].tag){
int l=p[o].lc,r=p[o].rc;
p[l].val=p[o].tag,p[r].val=p[o].tag;
p[o].tag=;
}
} void maintain(int o){
int l=p[o].lc,r=p[o].rc;
for(int i=;i<;i++){
p[o].mnn[i]=min(min(p[l].mnn[i],p[r].mnn[i]),p[o].x[i]);
p[o].mxn[i]=max(max(p[l].mxn[i],p[r].mxn[i]),p[o].x[i]);
}
}
void build(int &o,int l,int r,int d){
if(l>r){
o=;
return;
}
int m=l+(r-l)/;
p[m].tag=;
cmpNo=d,o=m;
nth_element(p+l,p+m,p+r+,cmp);
build(p[o].lc,l,m-,d^);
build(p[o].rc,m+,r,d^);
maintain(o);
}
bool all(int o){
if(p[o].mxn[]<=x.mxn[]&&p[o].mnn[]>=x.mnn[]&&p[o].mnn[]>=x.mnn[]&&p[o].mxn[]<=x.mxn[]){
return true;
}
return false;
}
bool have(int o){
if(p[o].mnn[o]<=x.mxn[]&&p[o].mxn[o]>=x.mnn[]&&p[o].mxn[]>=x.mnn[]&&p[o].mnn[]<=x.mxn[]){
return true;
}
return false;
}
void update(int o){
if(!o)return;
if(all(o)){
p[o].tag=x.tag;
p[o].val=x.tag;
return;
} pushdown(o);
int l=p[o].lc,r=p[o].rc;
if(p[o].x[]>=x.mnn[]&&p[o].x[]<=x.mxn[]&&p[o].x[]>=x.mnn[]&&p[o].x[]<=x.mxn[]){
p[o].val=x.tag;
}
if(all(l)){
p[l].tag=p[l].val=x.tag;
}else if(have(l)){
update(l);
}
if(all(r)){
p[r].tag=p[r].val=x.tag;
}else if(have(r)){
update(r);
}
}
int query(int o){
if(!o)return ;
if(p[o].u==x.u){
return p[o].val;
}
pushdown(o);
int l=p[o].lc,r=p[o].rc; if(p[l].mnn[]<=x.x[]&&p[l].mxn[]>=x.x[]&&x.x[]>=p[l].mnn[]&&x.x[]<=p[l].mxn[])
return query(l);
else
return query(r);
}
void init(){
sz=;
cnt=;
memset(head,-,sizeof(head));
}
void add_edge(int a,int b){
++sz;
to[sz]=b;
Next[sz]=head[a];
head[a]=sz;
}
void dfs(int u,int fa,int dep){
depth[u]=dep;
order[++cnt]=u;
indx[u]=cnt;
st[u]=cnt;
for(int i=head[u];i!=-;i=Next[i]){
int v=to[i];
if(v==fa)
continue;
dfs(v,u,dep+);
}
en[u]=cnt;
}
int main(){
scanf("%d",&T);
for(int kase=;kase<=T;kase++){
scanf("%d%d%d",&n,&c,&q);
init();
for(int i=;i<=n;i++){
int fa;
scanf("%d",&fa);
add_edge(fa,i);
add_edge(i,fa);
}
dfs(,-,);
for(int i=;i<=n;i++){
p[i].x[]=indx[i];
p[i].x[]=depth[i];
p[i].u=i;
p[i].val=;
p[i].tag=p[i].lc=p[i].rc=;
}
p[].mnn[]=p[].mnn[]=INF;
p[].mxn[]=p[].mxn[]=-INF;
build(root,,n,);
LL ans=;
for(int i=;i<=q;i++){
int a,l,c;
scanf("%d%d%d",&a,&l,&c);
if(c){
x.mnn[]=st[a],x.mxn[]=en[a],x.tag=c;
x.mnn[]=depth[a],x.mxn[]=depth[a]+l;
update(root);
}else{
x.u=a;
x.x[]=indx[a];
x.x[]=depth[a];
ans=(ans+(LL)i*query(root))%mod;
// printf("%d\n",query(root,0));
}
}
printf("%lld\n",ans);
}
return ;
}

【BZOJ4154】Generating Synergy【kd树】的更多相关文章

  1. BZOJ4154:[Ipsc2015]Generating Synergy(K-D Tree)

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

  2. 【BZOJ4154】[Ipsc2015]Generating Synergy KDtree

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

  3. BZOJ4154: [Ipsc2015]Generating Synergy

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

  4. K-D树

    一般用来解决各种二维平面的点对统计,也许一般非正解? 没时间慢慢写了,打完这个赛季后补细节 建树板子: #include <cstdio> #include <locale> ...

  5. 利用KD树进行异常检测

    软件安全课程的一次实验,整理之后发出来共享. 什么是KD树 要说KD树,我们得先说一下什么是KNN算法. KNN是k-NearestNeighbor的简称,原理很简单:当你有一堆已经标注好的数据时,你 ...

  6. 2016 ICPC青岛站---k题 Finding Hotels(K-D树)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5992 Problem Description There are N hotels all over ...

  7. kd树和knn算法的c语言实现

    基于kd树的knn的实现原理可以参考文末的链接,都是一些好文章. 这里参考了别人的代码.用c语言写的包括kd树的构建与查找k近邻的程序. code: #include<stdio.h> # ...

  8. PCL点云库:Kd树

    Kd树按空间划分生成叶子节点,各个叶子节点里存放点数据,其可以按半径搜索或邻区搜索.PCL中的Kd tree的基础数据结构使用了FLANN以便可以快速的进行邻区搜索.FLANN is a librar ...

  9. KNN算法与Kd树

    最近邻法和k-近邻法 下面图片中只有三种豆,有三个豆是未知的种类,如何判定他们的种类? 提供一种思路,即:未知的豆离哪种豆最近就认为未知豆和该豆是同一种类.由此,我们引出最近邻算法的定义:为了判定未知 ...

随机推荐

  1. css3动画的原理 及 各种效果制作

    1. 制作小球弹动效果 在这篇文章中,我们将会去探究一下浏览器是如何去处理CSS Animations和CSS Transitions的,   c 以便使你在写一些动画效果之前就可以对该动画在浏览器中 ...

  2. Mysql查询正在运行的事务以及杀掉它

    查询 正在执行的事务:SELECT * FROM information_schema.INNODB_TRX 根据这个事务的线程ID(trx_mysql_thread_id): 可以使用mysql命令 ...

  3. JMeter VS LoadRunner

    对比项 JMeter LoadRunner 安装 简单,下载解压即可 复杂,安装包大于1GB,安装时间较久 录制/回放模式 支持 支持 测试协议 偏少,但用户可自行拓展 较多,用户不可自行拓展 分布式 ...

  4. layui table 数据表格 隐藏列

    现在国内的模板,也就layui一家独大了,其中的数据表格功能强大,但我不会用python或者django拼接json,输出发送给数据表格,那只好用笨办法,循环遍历吧. 数据表格中保留id列,是为了编辑 ...

  5. (转) 一致性Hash算法在Memcached中的应用

    前言 大家应该都知道Memcached要想实现分布式只能在客户端来完成,目前比较流行的是通过一致性hash算法来实现.常规的方法是将 server的hash值与server的总台数进行求余,即hash ...

  6. 各开源 bbs 程序比较

    主要是集中在 php 开源轻巧的程序. 搜索到一个逼乎的一个帖子:https://www.zhihu.com/question/20655704 ,顺藤摸瓜 下. carbon forum 第一个测试 ...

  7. Zabbix(Windows)

    Windows环境下只能装客户端, 而不能装服务端; zabbix官网 https://www.zabbix.com/ 下载并解压到本地 修改配置文件: # Hostname=Hostname=DES ...

  8. mongodb,redis,mysql的区别和具体应用场景

    一.MySQL 关系型数据库. 在不同的引擎上有不同 的存储方式. 查询语句是使用传统的sql语句,拥有较为成熟的体系,成熟度很高. 开源数据库的份额在不断增加,mysql的份额页在持续增长. 缺点就 ...

  9. USB相关的sysfs文件

    主要来自driver/usb/core/sysfs.c: 1.bConfigurationValue RW,W时调用了usb_set_configuration()实时设置配置.根据USB规范(例如第 ...

  10. RabbitMQ消息队列安装

    [root@VM_119_179_centos ~]# rpm -ivh erlang-19.0.4-1.el6.x86_64.rpm [root@VM_119_179_centos ~]# rpm ...