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. Java的动态代理Proxy

    概念梳理: 1.什么是动态代理? 答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的接口.代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际 ...

  2. Shell基本概述

    目录 Shell01--基本概述 1. Shell课程大纲介绍 2. 什么是Shell ? 3. 什么是Shell脚本 ? 4. 为什么要学Shell编程 ? 5. 学习Shell编程需要哪些知识 ? ...

  3. Spring、SpringMVC、SpringBoot、SpringCloud概述

    spring和springMvc: 1. spring是一个一站式的轻量级的java开发框架,核心是控制反转(IOC)和面向切面(AOP),针对于开发的WEB层(springMvc).业务层(Ioc) ...

  4. Spring MVC processing flow

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484057.html DispatcherServlet receives the request. ...

  5. magento 站内优化和站外优化详解

    关于Magento如何如何我就不做评论了,一句话,谁用谁知道,搜索了下,百度和谷歌中文里还真没有一篇系统的关于magento seo的内容,花了一个上午的时间,稍微整理了一下,算是给新人一个指引吧.主 ...

  6. Java实现按汉语拼音的排序

    public class sortByPinyin { public static void main(String[] args) { String[] arr = { "刘刘" ...

  7. shell 逐行比较两个文件的内容是否一样(行数相同)

    file1="1.txt" file2="2.txt" lines=`cat $file1 | wc -l` ;i<=$lines;i++)) do li ...

  8. PHP disk_free_space() 函数

    定义和用法 disk_free_space() 函数返回指定目录的可用空间,以字节为单位. 语法 disk_free_space(directory) 参数 描述 directory 必需.规定要检查 ...

  9. PHP rewinddir() 函数

    打开一个目录,列出其中的文件,充值目录句柄,重新列出其中的文件,然后关闭: <?php$dir = "/images/"; // Open a directory, and ...

  10. hdu 1402 A * B Problem Plus (FFT模板)

    A * B Problem Plus Problem Description Calculate A * B. Input Each line will contain two integers A ...