BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】
题目分析:
很无聊的一道题目。首先区间内单点对应异或值的询问容易想到trie树。由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问。case2维护dfs序,对dfs序建可持久化的trie树。这样做的空间复杂度是O(nw),时间复杂度是O(nw).
代码:
#include<bits/stdc++.h>
using namespace std; const int maxn=; int n,q;
int v[maxn];
vector<int> g[maxn]; vector<pair<int,int> > qy[maxn];
vector<pair<int,int> > vec; int ans[maxn],num,kd[maxn];
int dep[maxn],dfsin[maxn],dfsout[maxn],fa[maxn]; vector<pair<int,int> > Lca[maxn];
int pre[maxn]; int found(int x){
int rx = x; while(pre[rx] != rx) rx = pre[rx];
while(pre[x] != rx){
int t = pre[x]; pre[x] = rx; x = t;
}
return rx;
} void dfs(int now,int dp,int f){
dfsin[now] = dfsout[now] = ++num;fa[now] = f; dep[now] = dp;
for(auto pr:Lca[now]){
if(dep[pr.first] == ) continue;
int la = found(pr.first);
qy[now].push_back(make_pair(la,pr.second));
qy[pr.first].push_back(make_pair(la,pr.second));
}
for(auto i:g[now]){
if(i == f) continue;
dfs(i,dp+,now);
dfsout[now] = dfsout[i];
}
pre[found(now)] = found(f);
} void read(){
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++) scanf("%d",&v[i]);
for(int i=;i<n;i++){
int x,y; scanf("%d%d",&x,&y);
g[x].push_back(y); g[y].push_back(x);
}
for(int i=;i<=q;i++){
int cas; scanf("%d",&cas);
if(cas == ){
int x,y; scanf("%d%d",&x,&y);
vec.push_back(make_pair(x,i));kd[i] = y;
}else{
int x,y,z; scanf("%d%d%d",&x,&y,&z);
Lca[x].push_back(make_pair(y,i));
if(x!=y) Lca[y].push_back(make_pair(x,i));
kd[i] = z;
}
}
for(int i=;i<=n;i++) pre[i] = i;
dfs(,,);
} int his[maxn],om;
int sz[maxn*],ch[maxn*][]; void follow(int pt,int last,int dt){
int hbit = ;
while(hbit!=-){
if((<<hbit)&dt){
ch[pt][] = ch[last][];
ch[pt][] = ++num;
pt = num; last = ch[last][];
sz[pt] = sz[last]+;
}else{
ch[pt][] = ch[last][];
ch[pt][] = ++num;
pt = num; last = ch[last][];
sz[pt] = sz[last]+;
}
hbit--;
}
} void ins(int now){
int last = his[om-];
num++;int pt = num; sz[pt] = sz[last]+;
his[om] = num;
follow(pt,last,v[now]);
} int query(int now,int last,int z){
now = his[now]; last = his[last];
int hbit = ;
while(hbit!=-){
if((<<hbit)&z){
if(sz[ch[now][]]-sz[ch[last][]]){
now = ch[now][];last = ch[last][];
}else{
z -= (<<hbit);now = ch[now][];last = ch[last][];
}
}else{
if(sz[ch[now][]]-sz[ch[last][]]){
z += (<<hbit);
now = ch[now][];last = ch[last][];
}else{
now = ch[now][];last = ch[last][];
}
}
hbit--;
}
return z;
} void del(int now){his[om] = ;} void dfs2(int now){
om++;ins(now);
for(auto pr:qy[now]){
int last = dep[pr.first]-,data = kd[pr.second];
ans[pr.second] = max(ans[pr.second],query(dep[now],last,data));
}
for(auto i:g[now]){
if(i == fa[now]) continue;
dfs2(i);
}
del(now);om--;
} void dfs3(int now){
om++;ins(now);
for(auto i:g[now]){
if(i == fa[now]) continue;
dfs3(i);
}
} void work(){
num = ;his[] = ;
dfs2();
memset(ch,,sizeof(ch));memset(sz,,sizeof(sz));
num = ;his[] = ;om = ;
dfs3();
for(auto pr:vec){
int st = dfsin[pr.first],ed = dfsout[pr.first];
ans[pr.second] = query(ed,st-,kd[pr.second]);
}
for(int i=;i<=q;i++) printf("%d\n",ans[i]);
} int main(){
read();
work();
return ;
}
BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】的更多相关文章
- [BZOJ5338][TJOI2018]xor(可持久化Trie)
可持久化Trie模板题. 建两种可持久化Trie,每个点两棵,一棵对DFS求前缀和,一棵对祖先求前缀和. 或者树剖,不好写多少还多个log. #include<cstdio> #inclu ...
- Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s 内存限制:512.0MB 总提交次数:196 AC次数:65 平均分: ...
- BZOJ.5338.[TJOI2018]xor(可持久化Trie)
BZOJ LOJ 洛谷 惊了,18年了还有省选出模板题吗= = 做这题就是练模板的,我就知道我忘的差不多了 询问一就用以DFS序为前缀得到的可持久化Trie做,询问二很经典的树上差分. 注意求询问二的 ...
- 【CF768G】The Winds of Winter 可持久化线段树 DFS序
题目大意 给定一棵\(n\)个点的树,对于树上每个结点,将它删去,然后可以将得到的森林中任意一个点与其父亲断开并连接到另一颗树上,对每一个点求出森林中所有树\(size\)最大值的最小值. \(n\l ...
- 2018.10.20 NOIP模拟 巧克力(trie树+dfs序+树状数组)
传送门 好题啊. 考虑前面的32分,直接维护后缀trietrietrie树就行了. 如果#号不在字符串首? 只需要维护第一个#前面的字符串和最后一个#后面的字符串. 分开用两棵trie树并且维护第一棵 ...
- BZOJ3653谈笑风生——可持久化线段树+dfs序
题目描述 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道 高明到哪里去了”. ? 设a 和 b 为 T 中的两个不同节点.如果 a ...
- BZOJ 5338: [TJOI2018]xor 可持久化trie+dfs序
强行把序列问题放树上,好无聊啊~ code: #include <bits/stdc++.h> #define N 200005 #define setIO(s) freopen(s&qu ...
- [TJOI2018] Xor 异或 (可持久化Trie,树链剖分)
题目描述 现在有一颗以 1 为根节点的由 n 个节点组成的树,树上每个节点上都有一个权值 \(v_i\).现在有 Q 次操作,操作如下: 1 x y :查询节点 x 的子树中与 y 异或结果的最大值. ...
- 可持久化trie(BZOJ5338: [TJOI2018]xor)
题面 BZOJ Sol 显然是要维护一个区域的 \(trie\) 树,然后贪心 区间 \(trie\) 树??? 可持久化 \(trie\) 树??? 直接参考主席树表示出区间的方法建立 \(trie ...
随机推荐
- Python写代码的时候为什么要注释?Sun因此被Oracle收购
导读: 此块分为:1.注释的重要性 2.如何正确注释 注释的重要性 在我们看代码的时候,会遇到很多看不懂得代码,特别是在做项目的时候,代码的注释以及命名习惯的重要性就有了为什么这么说呢? 因为在很多情 ...
- WPF CheckBox 滑块 样式 开关
原文:WPF CheckBox 滑块 样式 开关 效果图 样式代码 <Style x:Key="CheckRadioFocusVisual"> <Setter P ...
- (9)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- JWT算法
一. JWT 简介 内部 Restful 接口可以“我家大门常打开”,但是如果要给 app 等使用的接口,则需要做权限校验,不能谁都随便调用. Restful 接口不是 web 网站,App 中很难直 ...
- Ceph分布式存储集群-硬件选择
在规划Ceph分布式存储集群环境的时候,对硬件的选择很重要,这关乎整个Ceph集群的性能,下面梳理到一些硬件的选择标准,可供参考: 1)CPU选择Ceph metadata server会动态的重新分 ...
- mariadb第二章-增删改
MariaDB 数据类型 MariaDB数据类型可以分为数字,日期和时间以及字符串值. 使用数据类型的原则:够用就行, 尽量使用范围小的,而不用大的 常用的数据类型 整数:int, bit 小数:de ...
- mysql 编码和汉字存储占用字节问题的探索
MySql 5.5 之前,UTF8 编码只支持1-3个字节,只支持BMP这部分的unicode编码区,BMP是从哪到哪?基本就是 0000 ~ FFFF 这一区. 从MySQL 5.5 开始,可支持4 ...
- Daily Scrum NO.10
工作概况 今天是两周正是开发的最后一个工作日,虽然也是编译的DEADLINE,但成员们还是较为积极.计划内的工作基本都能够完成:线程池.异常清理器和动态爬取的功能.异常清理器界面的第一版也在今晚做了出 ...
- 20135327郭皓--Linux内核分析第八周 进程的切换和系统的一般执行过程
第八周 进程的切换和系统的一般执行过程 一.进程切换的关键代码switch_to分析 1.进程调度与进程调度的时机分析 不同类型的进程有不同的调度需求 第一种分类: I/O-bound:频繁进行I/O ...
- 网络:OSPF理解
OSPF(开放最短路径优先)协议使用Dijkstra算法,常见的版本有:OSPFv2.OSPFv3等.以下主要介绍OSPFv2,OSPFv3是面向IPv6的且不兼容IPv4. 1.工作过程: 1)每台 ...
- answer my questions from the book<构建之法>.
1)何为文档:文档时在一个项目进行的一生中所有记忆的集合.有需求分析.功能设计.在实现功能过程中也可以有一系列文档记录.测试文档等等. 2)结对工作等找队友会花费大量时间致耽误项目否:正如老师所讲,从 ...