题目

大概已经掌握熟练码出\(kdt\)的技能了

发现距离子树根节点\(x\)不超过\(l\)的点可以用两种方式来限制,首先\(dfs\)序在\([dfn_x,dfn_x+sum_x)\)中,深度自然也要满足\([deep_x,deep_x+l]\)

发现这变成了对一个子矩形染色同时询问单点颜色的题目

我们直接\(kdt\)打标机就好了

需要注意的一点是,仅对\(kdt\)中子树的根进行的修改不打标机

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||x>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int mod=1e9+7;
const int maxn=1e5+5;
struct E{int v,nxt;}e[maxn];
int head[maxn],deep[maxn],sum[maxn],dfn[maxn];
struct Point{int x[2];}p[maxn],t;
int n,num,cnt,__,op,T,C,m;
int x1,x2,y1,y2;
int l[maxn],r[maxn],tag[maxn],col[maxn],mx[maxn][2],mi[maxn][2],id[maxn];
inline void add(int x,int y) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
inline int cmp(Point A,Point B) {
if(A.x[op]==B.x[op]) return A.x[op^1]<B.x[op^1];
return A.x[op]<B.x[op];
}
void dfs(int x) {
dfn[x]=++__;sum[x]=1;
for(re int i=head[x];i;i=e[i].nxt) {
deep[e[i].v]=deep[x]+1;
dfs(e[i].v);
sum[x]+=sum[e[i].v];
}
}
inline void pushup(int k) {
mx[k][0]=mi[k][0]=p[id[k]].x[0];
mx[k][1]=mi[k][1]=p[id[k]].x[1];
for(re int i=0;i<2;i++) {
if(l[k]) mx[k][i]=max(mx[k][i],mx[l[k]][i]),
mi[k][i]=min(mi[k][i],mi[l[k]][i]);
if(r[k]) mx[k][i]=max(mx[k][i],mx[r[k]][i]),
mi[k][i]=min(mi[k][i],mi[r[k]][i]);
}
}
inline void pushdown(int k) {
if(tag[k]==-1) return;
tag[r[k]]=tag[l[k]]=tag[k];
col[l[k]]=col[r[k]]=tag[k];
tag[k]=-1;
}
int build(int x,int y,int o) {
if(x>y) return 0;
int mid=x+y>>1,k=++cnt;col[k]=1;
op=o;std::nth_element(p+x,p+mid,p+y+1,cmp);id[k]=mid;
l[k]=build(x,mid-1,o^1);r[k]=build(mid+1,y,o^1);
pushup(k);return k;
}
int ask(int k,int o) {
if(t.x[0]==p[id[k]].x[0]&&t.x[1]==p[id[k]].x[1])
return col[k];
pushdown(k);
if(t.x[o]==p[id[k]].x[o]) {
if(t.x[o^1]<p[id[k]].x[o^1]) return ask(l[k],o^1);
return ask(r[k],o^1);
}
if(t.x[o]<p[id[k]].x[o]) return ask(l[k],o^1);
if(t.x[o]>p[id[k]].x[o]) return ask(r[k],o^1);
}
inline int out(int k) {
return (mx[k][0]<x1||mi[k][0]>x2||mx[k][1]<y1||mi[k][1]>y2);
}
inline int in(int k) {
return (mi[k][0]>=x1&&mx[k][0]<=x2&&mi[k][1]>=y1&&mx[k][1]<=y2);
}
inline int chk(Point a) {
return (a.x[0]>=x1&&a.x[0]<=x2&&a.x[1]>=y1&&a.x[1]<=y2);
}
void change(int k,int c) {
if(!k||out(k)) return;
pushdown(k);
if(in(k)) {col[k]=c,tag[k]=c;return;}
if(chk(p[id[k]])) col[k]=c;
change(l[k],c);change(r[k],c);
}
int main() {
T=read();
while(T--) {
n=read(),C=read(),m=read();num=0;cnt=0;
memset(head,0,sizeof(head));
memset(mx,0,sizeof(mx));
memset(mi,0,sizeof(mi));
memset(tag,-1,sizeof(tag));
for(re int x,i=2;i<=n;i++)
x=read(),add(x,i);
deep[1]=1,dfs(1);
for(re int i=1;i<=n;i++)
p[i].x[0]=dfn[i],p[i].x[1]=deep[i];
build(1,n,0);int ans=0;
for(re int x,c,l,i=1;i<=m;i++) {
x=read(),l=read(),c=read();
if(!c) {
t.x[0]=dfn[x];
t.x[1]=deep[x];
ans=(ans+1ll*i*ask(1,0)%mod)%mod;
continue;
}
x1=dfn[x],x2=dfn[x]+sum[x]-1;
y1=deep[x],y2=deep[x]+l;
change(1,c);
}
printf("%d\n",ans);
}
return 0;
}

【bzoj 4154】[Ipsc2015]Generating Synergy的更多相关文章

  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. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  4. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  5. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  6. LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego

    [bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...

  7. 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...

  8. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

  9. 【BZOJ 2132】圈地计划 && 【7.22Test】计划

    两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...

随机推荐

  1. portable-net45+win8

    <PropertyGroup> <TargetFramework>netcoreapp1.1</TargetFramework> <RuntimeFramew ...

  2. ADO----nDSN

    //////////////链接数据库 非DSN模式/////////////////////////////    //CString strOpen="DSN=DBAddressBook ...

  3. JAVA基础之——三大特征、接口和抽象类区别、重载和重写区别、==和equals区别、JAVA自动装箱和拆箱

    1 java三大特征 1)封装:即class,把一类实体定义成类,该类有变量和方法. 2)继承:从已有的父类中派生出子类,子类实现父类的抽象方法. 3)多态:通过父类对象可以引用不同的子类,从而实现不 ...

  4. mybatis-plus之Mapper CRUD接口和 Service CRUD 接口

    中文官网链接: https://mp.baomidou.com/guide/crud-interface.html

  5. zookeeper 典型应用

    一.发布/订阅 配置文件的集中管理. 问题:当分布式系统变多后,每个系统保存相应的配置文件,会造成同个文件有多份,修改起来非常麻烦. 解决方法:使用zk的发布/订阅功能,配合Watcher机制,在应用 ...

  6. hashlib模块 md5 sha1

    Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示) 对于同一个字符串,不管这个字符串有多长 ...

  7. Yii 日期时间过滤列 filter

    在yii使用过程中,我们经常要使用到 按时间区间来检索数据 用gridview自身的filter就无法满足我们得需求. 下面可以用插件的方式来搞定: sydatecolumn 下载地址:http:// ...

  8. LOJ #2985. 「WC2019」I 君的商店

    传送门 搬题解QwQ 首先最大值一定为 \(1\),直接扫一遍两两比较 \(O(2N)\) 求出最大值 设最大值位置为 \(a\),对于任意两个没有确定的位置 \(x,y\) 询问 \([a,x+y] ...

  9. 移动端地区选择mobile-select-area插件的使用方法

    顾名思义,mobile-select-area插件就是使用在移动端上的进行地区选择的插件,而且使用方法简单,我就说我是怎么用的吧 一.准备工作 首先肯定要下载插件对应的css+js文件, 当你下载好这 ...

  10. iframe跨源报错:"Blocked a frame with origin from accessing a cross-origin frame"

    一.报错信息: “Blocked a frame with origin from accessing a cross-origin frame” 二.在stackoverflow上找到原因 Same ...