题目分析:

  很无聊的一道题目。首先区间内单点对应异或值的询问容易想到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序】的更多相关文章

  1. [BZOJ5338][TJOI2018]xor(可持久化Trie)

    可持久化Trie模板题. 建两种可持久化Trie,每个点两棵,一棵对DFS求前缀和,一棵对祖先求前缀和. 或者树剖,不好写多少还多个log. #include<cstdio> #inclu ...

  2. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  3. BZOJ.5338.[TJOI2018]xor(可持久化Trie)

    BZOJ LOJ 洛谷 惊了,18年了还有省选出模板题吗= = 做这题就是练模板的,我就知道我忘的差不多了 询问一就用以DFS序为前缀得到的可持久化Trie做,询问二很经典的树上差分. 注意求询问二的 ...

  4. 【CF768G】The Winds of Winter 可持久化线段树 DFS序

    题目大意 给定一棵\(n\)个点的树,对于树上每个结点,将它删去,然后可以将得到的森林中任意一个点与其父亲断开并连接到另一颗树上,对每一个点求出森林中所有树\(size\)最大值的最小值. \(n\l ...

  5. 2018.10.20 NOIP模拟 巧克力(trie树+dfs序+树状数组)

    传送门 好题啊. 考虑前面的32分,直接维护后缀trietrietrie树就行了. 如果#号不在字符串首? 只需要维护第一个#前面的字符串和最后一个#后面的字符串. 分开用两棵trie树并且维护第一棵 ...

  6. BZOJ3653谈笑风生——可持久化线段树+dfs序

    题目描述 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道 高明到哪里去了”. ? 设a 和 b 为 T 中的两个不同节点.如果 a ...

  7. BZOJ 5338: [TJOI2018]xor 可持久化trie+dfs序

    强行把序列问题放树上,好无聊啊~ code: #include <bits/stdc++.h> #define N 200005 #define setIO(s) freopen(s&qu ...

  8. [TJOI2018] Xor 异或 (可持久化Trie,树链剖分)

    题目描述 现在有一颗以 1 为根节点的由 n 个节点组成的树,树上每个节点上都有一个权值 \(v_i\).现在有 Q 次操作,操作如下: 1 x y :查询节点 x 的子树中与 y 异或结果的最大值. ...

  9. 可持久化trie(BZOJ5338: [TJOI2018]xor)

    题面 BZOJ Sol 显然是要维护一个区域的 \(trie\) 树,然后贪心 区间 \(trie\) 树??? 可持久化 \(trie\) 树??? 直接参考主席树表示出区间的方法建立 \(trie ...

随机推荐

  1. Attention[Content]

    0. 引言 神经网络中的注意机制就是参考人类的视觉注意机制原理.即人眼在聚焦视野区域中某个小区域时,会投入更多的注意力到这个区域,即以"高分辨率"聚焦于图像的某个区域,同时以&qu ...

  2. CF1105E Helping Hiasat 最大团

    传送门 发现自己不会求最大团了可海星 如果将每一个朋友看做点,将两个\(1\)之间存在\(2\)操作的所有朋友之间互相连边,那么我们最后要求的就是这个图的最大独立集. 某个图的最大独立集就是反图的最大 ...

  3. mysql中Error : Invalid default value for 'timestamp'问题

    在执行mysql数据库时报错       timestamp给默认值出问题. 原因是:mysql的配置参数中sql_node中NO_ZERO_IN_DATE, NO_ZERO_DATE控制了times ...

  4. Scala学习(四)---映射和元组

    映射和元组 摘要: 一个经典的程序员名言是:"如果只能有一种数据结构,那就用哈希表吧".哈希表或者更笼统地说映射,是最灵活多变的数据结构之一.映射是键/值对偶的集合.Scala有一个通用的叫法:元组, ...

  5. SAAS云平台搭建札记: (二) Linux Ubutu下.Net Core整套运行环境的搭建

    最近做的项目,由于预算有限,公司决定不采购Windows服务器,而采购基于Linux的服务器. 一般的VPS服务器,如果使用Windows系统,那么Windows Server2012\2016安装好 ...

  6. InnoDB 文件系统

    1. 操作系统文件系统inode 2. InnoDB的存储结构 2.1Innodb inode page 参考 http://mysql.taobao.org/monthly/2016/02/01/ ...

  7. 在线排错之curl命令详解

    春回大地万物复苏,好久不来,向各位博友问好. 简介 cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行.它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下 ...

  8. ABP+AdminLTE+Bootstrap Table权限管理系统第三节--abp分层体系,实体相关及ABP模块系统

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 ABP模块系统 说了这么久,还没有详细说到abp框架,abp其实基于DDD(领域驱动设计)原则的细看分层如下: 再 ...

  9. Jmeter(三十三)_JsonPath表达式提取响应

    我们在用jmeter做接口测试的时候,有的时候会遇到一些复杂的json响应.比如多层list嵌套时的取值 一个简单的例子: $..Name:列出所有省份 $..Province[0].Name 提取P ...

  10. Linux Namespace : PID

    PID namespace 用来隔离进程的 PID 空间,使得不同 PID namespace 里的进程 PID 可以重复且互不影响.PID namesapce 对容器类应用特别重要, 可以实现容器内 ...