Description

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

区间修改单点查询kdtree

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#define LL long long
using namespace std; const int P=1e9+7;
const int M=100005;
struct vv{ int c,l,r,mx[2],mn[2],d[2],tag,D; } t[M];
int n,m,k,a[M],C,D,X1,Y1,X2,Y2,x,y,z;
int dfn[M],s[M],dp[M],f[M],T,root;
int ver[M],edge[M],nex[M],head[M],cnt,res; void add(int x,int y)
{
ver[++cnt]=y, nex[cnt]=head[x], head[x]=cnt;
} void dfs(int x)
{
dfn[x]=++cnt; dp[x]=dp[f[x]]+1; s[x]=1;
for(int i=head[x];i;i=nex[i]) dfs(ver[i]), s[x]+=s[ver[i]];
} bool cmp(vv a,vv b)
{
return a.d[D]==b.d[D]?a.d[!D]<b.d[!D] : a.d[D]<b.d[D];
} void update(int now)
{
if(t[now].l)
{
t[now].mn[0]=min(t[now].mn[0], t[t[now].l].mn[0]);
t[now].mn[1]=min(t[now].mn[1], t[t[now].l].mn[1]);
t[now].mx[0]=max(t[now].mx[0], t[t[now].l].mx[0]);
t[now].mx[1]=max(t[now].mx[1], t[t[now].l].mx[1]);
}
if(t[now].r)
{
t[now].mn[0]=min(t[now].mn[0], t[t[now].r].mn[0]);
t[now].mn[1]=min(t[now].mn[1], t[t[now].r].mn[1]);
t[now].mx[0]=max(t[now].mx[0], t[t[now].r].mx[0]);
t[now].mx[1]=max(t[now].mx[1], t[t[now].r].mx[1]);
}
} void pd(int now)
{
if(!t[now].tag) return ;
if(t[now].l) t[t[now].l].tag=t[t[now].l].c=t[now].tag;
if(t[now].r) t[t[now].r].tag=t[t[now].r].c=t[now].tag;
t[now].tag=0;
} int built(int l,int r,int d)
{
D=rand()&1; int mid=(l+r)>>1; nth_element(t+l,t+mid,t+r+1,cmp);
t[mid].tag=0; t[mid].c=1; t[mid].l=t[mid].r=0; t[mid].D=D; if(l<mid) t[mid].l=built(l,mid-1,!d);
if(mid<r) t[mid].r=built(mid+1,r,!d); update(mid);
return mid;
} void mody(int now,int c)
{
if(X1<=t[now].mn[0] && X2>=t[now].mx[0] && Y1<=t[now].mn[1] && Y2>=t[now].mx[1])
{
t[now].tag=t[now].c=c; return ;
}
if(X1>t[now].mx[0] || X2<t[now].mn[0] || Y1>t[now].mx[0] || Y2<t[now].mn[1]) return;
pd(now);
if(t[now].d[0]>=X1 && t[now].d[0]<=X2 && t[now].d[1]>=Y1 && t[now].d[1]<=Y2) t[now].c=c; if(t[now].l) mody(t[now].l,c);
if(t[now].r) mody(t[now].r,c);
} int ask(int now,int x,int y,int d)
{
if(t[now].tag) return t[now].tag; d=t[now].D;
if(t[now].d[0]==x && t[now].d[1]==y) return t[now].c;
if(!d)
{
if(x<t[now].d[0] || (x==t[now].d[0] && y<t[now].d[1])) return ask(t[now].l,x,y,!d);
else return ask(t[now].r,x,y,!d);
}
else
{
if(y<t[now].d[1] || (y==t[now].d[1] && x<t[now].d[0])) return ask(t[now].l,x,y,!d);
else return ask(t[now].r,x,y,!d);
}
} int main()
{
srand(time(0));
scanf("%d",&T);
for(;T;T--)
{
memset(nex,0,sizeof(nex));
memset(head,0,sizeof(head));
cnt=0;
scanf("%d%d%d",&n,&C,&m);
for(int i=2;i<=n;i++)
{
scanf("%d",&f[i]);
add(f[i],i);
}
dp[1]=1;cnt=0; dfs(1);
for(int i=1;i<=n;i++)
{
t[i].d[0]=t[i].mx[0]=t[i].mn[0]=dfn[i];
t[i].d[1]=t[i].mx[1]=t[i].mn[1]=dp[i];
}
root=built(1,n,0);
LL res=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
if(!z) res=(res+1ll*i*ask(root,dfn[x],dp[x],0))%P;
else
{
X1=dfn[x], X2=dfn[x]+s[x]-1, Y1=dp[x], Y2=dp[x]+y;
mody(root,z);
}
}
printf("%lld\n",res);
}
}

4154: [Ipsc2015]Generating Synergy的更多相关文章

  1. BZOJ 4154: [Ipsc2015]Generating Synergy KDtree+dfs序

    多组数据真tm恶心~ 把 $dfs$序和深度分别看作横纵坐标,然后用 $KDtree$ 数点就可以了~ #include <cstdio> #include <cstring> ...

  2. 【BZOJ4154】[Ipsc2015]Generating Synergy KDtree

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

  3. 【bzoj 4154】[Ipsc2015]Generating Synergy

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

  4. BZOJ4154:[IPSC2015]Generating Synergy

    浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...

  5. BZOJ4154: [Ipsc2015]Generating Synergy

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

  6. 【kd-tree】bzoj4154 [Ipsc2015]Generating Synergy

    区间修改的kd-tree,打标记,下传. 每次询问的时候,从询问点向上找到根,然后依次下传下来,再回答询问. #include<cstdio> #include<algorithm& ...

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

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

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

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

  9. [bzoj4154][Ipsc2015]Generating Synergy_KD-Tree_dfs序

    Generating Synergy bzoj-4154 Ipsc-2015 题目大意:给定一棵n个节点树,m个操作,支持:将一个点周围所有距该点距离不超过l的子结点的颜色改成另一种颜色:查询单点颜色 ...

随机推荐

  1. 关于array_merge()的注意

    array_merge() 函数把两个或多个数组合并为一个数组. 1 如果键名有重复,该键的键值为最后一个键名对应的值(后面的覆盖前面的). 2 如果数组是数字索引的,则键名会以连续方式重新索引. 2 ...

  2. leetcode.分治.241为运算表达式设计优先级-Java

    1. 具体题目 给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果.你需要给出所有可能的组合的结果.有效的运算符号包含 +, - 以及 * . 示例 1: 输入: & ...

  3. C++异常处理的深入理解

    1,问题: 1,如果在 main 函数中抛出异常会发生什么? 1,不处理,则崩溃: 2,如果异常不处理,最后会传到哪里? 3,下面的代码输出什么? 4,异常的最终处理编程实验: #include &l ...

  4. Regular Expression 範例

    Regular expression 被實作於各種語言中,可以用來對字串做 比對 擷取 分隔 這幾類的處理.以下是 JavaScript的處理範例. 各位看官,可以按F12開啟 brower 的 de ...

  5. 【BZOJ2138】stone

    题目 好厉害的题啊 这道题不难看成一个二分图模型,但是给人一种求最大匹配的感觉,这实在不是很好求的样子,于是自闭了 但是不妨这样来考虑,对于一个需求\(k_i\),我们求一个最大的\(x\leq k_ ...

  6. Centos安装IDEA

    1.官网下载tar包 到https://www.jetbrains.com/idea 下载对应版本的文件 将其解压 tar zvxf idea下载文件.tar 进入到解压后文件夹的bin目录下执行 . ...

  7. (playbook)ubuntu下ansible安装docker

    --- - hosts: test sudo: yes vars: apt_packages_ca: - apt-transport-https - ca-certificates tasks: - ...

  8. PostgreSQL的学习-序列

    序列对象(也叫序列生成器)都是用CREATE SEQUENCE创建的特殊的单行表.一个序列对象通常用于为行或者表生成唯一的标识符.下面序列函数,为我们从序列对象中获取最新的序列值提供了简单和并发读取安 ...

  9. Python 第三天学习整理2

    一.常用的字符串方法 capitalize() #将字符串首字母大写 center(100,'*') #把字符串居中的 count(‘zhou’)#查询次数 endswith('.jpg ')#判断字 ...

  10. JavaScript 下载大文件解决方案(Blob+OjbectURL)

    结合Blob和OjbectURL实现更大的文件下载: var a = document.createElement('a'); var txt = '.....content....'; for(va ...