题目分析:

  很无聊的一道题目。首先区间内单点对应异或值的询问容易想到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. linux源码分析 - 进程

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 最近在回想一些知识点的时候,觉得对进程这一块有些模糊,特别写一篇随笔对进程信息进行巩固和复习. 程序和进程 以我 ...

  2. 初识Identity(二)

    本文参考了[ASP.NET Identity系列教程(一)]ASP.NET Identity入门 一.Identity使用前准备项目 本文创建了一个名称为Users的项目.在创建过程中选择了“Empt ...

  3. ActiveMQ在C#中的应用

    本文是在.NET Framework框架下的应用,截止到目前ActiveMQ还不支持.NET Core,而RabbitMQ已经支持.NET Core,希望ActiveMQ能尽快支持. ActiveMQ ...

  4. Flutter - 本地化语言

    Flutter有很多本地化的packages使用,我现在用的是 flutter_i18n 项目主页:https://pub.dartlang.org/packages/flutter_i18n 1.安 ...

  5. 轮廓(Outline) 实例

    1.在元素周围画线本例演示使用outline属性在元素周围画一条线. <style type="text/css"> p{border:red solid thin;o ...

  6. Ubuntu16.04下安装QQ的完整操作记录(经验证可用)

    本机安装了Ubuntu16.04系统,用于日常运维办公.打算在Ubuntu上安装QQ,如下操作记录也使用于Ubuntu18.04: 1)先下载特制的QQ程序包(其实就是基于Wine容器做了一些封装,程 ...

  7. 自动化批量管理工具salt-ssh - 运维小结

    根据以往运维工作中操作经验来说,当管理上百台上千台服务器时,选择一款批量操作工具是及其有必要的.早期习惯于在ssh信任关系的前提下做for;do;done循环语句的批量操作,后来逐渐趋于使用批量工具操 ...

  8. mac下查看和设置环境变量

    1.查看环境变量 命令    env 2.修改环境变量 命令    cd ~ && ls -a && sudo vim .bashrc 编辑输入要添加的环境变量 3.s ...

  9. 10 分钟理解 BFC 原理

    一.常见定位方案 在讲 BFC 之前,我们先来了解一下常见的定位方案,定位方案是控制元素的布局,有三种常见方案: 普通流 (normal flow) 在普通流中,元素按照其在 HTML 中的先后位置至 ...

  10. hashContext

    java.lnag.Object中对hashCode的约定: 1. 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必 ...