BZOJ - 4771 七彩树 (可持久化线段树合并)
对每个结点建立两棵线段树,一棵记录该结点的子树下每种颜色对应的最小深度,另一棵记录子树下的每个深度有多少结点(每种颜色的结点只保留最浅的深度即可),自底而上令父节点继承子结点的线段树,如果合并两棵颜色线段树时发现某种颜色重复,则在深度线段树上把较深的深度对应的位置-1。
注意由于强制在线,深度线段树的合并以及更新都需要可持久化。
(ps:不能用map代替颜色线段树,会TLE~~)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=1e5+;
int n,m,hd[N],ne,rt1[N],rt2[N],tot1,tot2,a[N],dep[N];
struct E {int v,nxt;} e[N];
struct D1 {int ls,rs,x;} tr1[N*];
struct D2 {int ls,rs,x;} tr2[N*];
void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
#define mid ((l+r)>>1)
int newnode1() {tr1[++tot1]= {,,}; return tot1;}
int newnode2() {tr2[++tot2]= {,,}; return tot2;}
void upd1(int& u,int p,int x,int l=,int r=n) {
if(!u)u=newnode1();
if(l==r) {tr1[u].x=x; return;}
p<=mid?upd1(tr1[u].ls,p,x,l,mid):upd1(tr1[u].rs,p,x,mid+,r);
}
void upd2(int& w,int u,int p,int x,int l=,int r=n) {
w=newnode2();
tr2[w].x=tr2[u].x+x;
if(l==r)return;
if(p<=mid)upd2(tr2[w].ls,tr2[u].ls,p,x,l,mid),tr2[w].rs=tr2[u].rs;
else upd2(tr2[w].rs,tr2[u].rs,p,x,mid+,r),tr2[w].ls=tr2[u].ls;
}
void mg1(int uu,int& u,int v,int l=,int r=n) {
if(!u) {u=v; return;}
if(!v)return;
if(l==r) {
if(!tr1[u].x)tr1[u].x=tr1[v].x;
else if(!tr1[v].x);
else {
int mx=max(tr1[u].x,tr1[v].x),mi=min(tr1[u].x,tr1[v].x);
upd2(rt2[uu],rt2[uu],mx,-),tr1[u].x=mi;
}
return;
}
mg1(uu,tr1[u].ls,tr1[v].ls,l,mid);
mg1(uu,tr1[u].rs,tr1[v].rs,mid+,r);
}
void mg2(int& w,int u,int v,int l=,int r=n) {
if(!u) {w=v; return;}
if(!v) {w=u; return;}
w=newnode2();
tr2[w].x=tr2[u].x+tr2[v].x;
if(l==r)return;
mg2(tr2[w].ls,tr2[u].ls,tr2[v].ls,l,mid);
mg2(tr2[w].rs,tr2[u].rs,tr2[v].rs,mid+,r);
}
void dfs(int u,int d) {
rt1[u]=rt2[u]=,dep[u]=d;
upd1(rt1[u],a[u],dep[u]),upd2(rt2[u],rt2[u],dep[u],);
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
dfs(v,d+);
mg1(u,rt1[u],rt1[v]);
mg2(rt2[u],rt2[u],rt2[v]);
}
}
int qry(int u,int L,int R,int l=,int r=n) {
if(l>=L&&r<=R)return tr2[u].x;
if(l>R||r<L)return ;
return qry(tr2[u].ls,L,R,l,mid)+qry(tr2[u].rs,L,R,mid+,r);
}
int main() {
int T;
for(scanf("%d",&T); T--;) {
memset(hd,-,sizeof hd),ne=tot1=tot2=;
scanf("%d%d",&n,&m);
for(int i=; i<=n; ++i)scanf("%d",&a[i]);
for(int i=; i<=n; ++i) {
int f;
scanf("%d",&f);
addedge(f,i);
}
dfs(,);
for(int ans=; m--;) {
int u,d;
scanf("%d%d",&u,&d),u^=ans,d^=ans;
printf("%d\n",ans=qry(rt2[u],,min(dep[u]+d,n)));
}
}
return ;
}
BZOJ - 4771 七彩树 (可持久化线段树合并)的更多相关文章
- [BZOJ 4771]七彩树(可持久化线段树+树上差分)
[BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...
- 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex
题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...
- BZOJ.4771.七彩树(可持久化线段树)
BZOJ 考虑没有深度限制,对整棵子树询问怎么做. 对于同种颜色中DFS序相邻的两个点\(u,v\),在\(dfn[u],dfn[v]\)处分别\(+1\),\(dfn[LCA(u,v)]\)处\(- ...
- BZOJ 4771: 七彩树 可持久化线段树+树链的并
这个思路挺有意思的 ~ 利用树链的并来保证每个颜色只贡献一次,然后用可持久化线段树维护 code: #include <set> #include <cstdio> #incl ...
- BZOJ4771七彩树——可持久化线段树+set+树链的并+LCA
给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节 点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色.定义dept ...
- BZOJ 3483 SGU505 Prefixes and suffixes(字典树+可持久化线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3483 [题目大意] 给出一些串,同时给出m对前缀后缀,询问有多少串满足给出的前缀后缀模 ...
- bzoj 2653 二分答案+可持久化线段树
首先离散化,然后我们知道如果对于一个询问的区间[l1,r1],[l2,r2],我们二分到一个答案x,将[l1,r2]区间中的元素大于等于x的设为1,其余的设为-1,那么如果[l1,r1]的最大右区间和 ...
- BZOJ 3439 Kpm的MCpassword Trie树+可持久化线段树
题目大意:给定n个字符串,对于每一个字符串求以这个字符串为后缀的字符串中第k小的编号 首先将字符串反转 那么就变成了对于每一个字符串求以这个字符串为前缀的字符串中第k小的编号 然后考虑对字符串排序 那 ...
- 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665
如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...
- 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )
在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...
随机推荐
- CodeForces - 920F SUM and REPLACE (线段树)
题意:给N个数M次操作,(1<=N,M<=3e5, 1<=ai<=1e6),1是使[L,R]中的每个元素变成其因子的个数之和:2是求[L,R]区间之和 分析:看上去就很线段树的 ...
- 软件测试工程师的Linux之路(持续更新修正)
软件测试工程师成长必经之路—Linux学习. 测试工程师不同于运维工程师,所以在对不熟悉Linux的测试人员来说,先了解一些Linux系统的基本操作,能顺利开展测试工作即可,在强迫自己使用,熟悉命令行 ...
- Linux 进程管理 进程优先级管理
Linux进程优先级 Linux 是一个多用户.多任务的操作系统,系统中通常运行着非常多的进程.但是 CPU 在一个时钟周期内只能运算一条指令(现在的 CPU 采用了多线程.多核心技术,所以在一个时钟 ...
- HashMap的简单源码分析(看了大佬的源码,基于1.7) put方法
参考博客: https://blog.csdn.net/eson_15/article/details/51158865 hashMap中的几个关键属性 //默认初始容量是16,必须是2的幂 stat ...
- SpringBoot和Mycat动态数据源项目整合
SpringBoot项目整合动态数据源(读写分离) 1.配置多个数据源,根据业务需求访问不同的数据,指定对应的策略:增加,删除,修改操作访问对应数据,查询访问对应数据,不同数据库做好的数据一致性的处理 ...
- 电脑 HOST 文件
路径: C:\Windows\System32\drivers\etc\HOSTS
- spring通知的注解
1.代理类接口Person.java package com.xiaostudy; /** * @desc 被代理类接口 * * @author xiaostudy * */ public inter ...
- 使用Xcode IDE写node.js
最近在玩node.js 但是发现很多IDE就是用不顺手 后来发现Xcode可以剖析java script 于是试着使用Xcode来当做node.js的编辑器 首先,在Mac上必须先安装node.js的 ...
- CocoaPods学习系列5——错误集锦
这篇文章记录使用CocoaPods过程中遇到的一些错误. 1.error:include of non-modular header inside framework module 在自定义类库中,引 ...
- Spring -- spring整合struts2
1. 概述 spring和struts整合: 1.创建web程序 2.引入struts2类库. 3.创建HelloWorldAction package cn.itcast.struts2.actio ...