题目

大概已经掌握熟练码出\(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. Android Studio 3.0找不到Android Device Monitor

    因为自Android Studio 3.0开始弃用Android Device Monitor,Android Developers官网上的原话是: Android Device Monitor is ...

  2. TCP三次握手是什么?为什么要进行三次握手?两次,四次握手可以吗?

    1.第一次握手,发送SYN报文,传达信息:“你好,我想建立连接”: 第二次握手,回传SYN+ACK报文,传达信息:“好的,可以建立链接”:    第三次握手,回传ACK报文,传到信息:“好的,我知道了 ...

  3. Android Studio 1.1.0汉化初步出炉!

    我找到去年12月国人汉化的版本,然后迁移上来的.实测支持Android window最新版(1.1.0) 项目分4部分:1压缩好的:2文本分析器:3原生的语言包:4原版语言包备份 现在一些新增的项目没 ...

  4. 撩课-Web大前端每天5道面试题-Day17

    1.apply, call和bind有什么区别? 三者都可以把一个函数应用到其他对象上,注意不是自身对象. apply,call是直接执行函数调用,bind是绑定,执行需要再次调用. apply和ca ...

  5. idea创建maven的web工程

    然后一路点next 接下去添加tomcat 成功 控制台出现乱码的话 输入:-Dfile.encoding=UTF-8 控制台乱码解决

  6. Linux 文件缓存 (二)

    close系统调用入口1. 首先来到系统调用入口,主要使用__close_fd进行了具体的处理过程,并没有耗时操作.(current->files表示进程当前打开文件表信息,fd为需要关闭的文件 ...

  7. 连接数据库 JDBC、DBCP、JNDI

    一.JDBC package com.direct.util; import java.sql.Connection; import java.sql.DriverManager; import ja ...

  8. 神奇的Flex 布局

    layout是css中的一个重点.传统的页面布局是盒子模型,依赖 display属性 ,position属性 , float属性.它对于那些特殊布局非常不方便,而且定位用多了会出现挺多的bug. 所以 ...

  9. Spring Boot—03REST请求

    package com.smartmap.sample.ch1.controller.rest; import java.util.List; import org.apache.commons.lo ...

  10. keras Lambda 层

    Lambda层 keras.layers.core.Lambda(function, output_shape=None, mask=None, arguments=None) 本函数用以对上一层的输 ...