题目大意:

有一棵树,根节点为1。每个点有点权。有两种操作。

1. 求节点x所在子树中点权与y异或的最大值。
2. 求x到y的路径上点权与z异或的最大值。

解题思路:

可持久化字典树。

对于第一种操作,我们对树进行dfs遍历,求出每个节点的dfs序(树剖),然后由于子树中dfs序连续,所以相当于区间的询问。对每个1~x区间建trie即可。

对于第二种操作,我们对每个节点建一颗trie,记录其到根的路径上的信息。

然后常规求LCA,减一减即可。

C++ Code:

#include<bits/stdc++.h>
const int N=1e5+5;
int ch[N<<6][2],siz[N<<6],ccnt=0,n,q,a[N],head[N],to[N<<1],nxt[N<<1];
int sz[N],dep[N],son[N],top[N],trie1[N],trie2[N],dfn[N],idfn[N],idx=0,fa[N],ans;
inline int readint(){
int c=getchar(),d=0;
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())
d=(d<<3)+(d<<1)+(c^'0');
return d;
}
void Insert(int&nw,int&o,int&p,int pp=30){
nw=++ccnt;
if(!~pp)return(void)(siz[nw]=siz[o]+1);
ch[nw][0]=ch[o][0];
ch[nw][1]=ch[o][1];
int nxt=(p>>pp)&1;
Insert(ch[nw][nxt],ch[o][nxt],p,pp-1);
siz[nw]=siz[ch[nw][0]]+siz[ch[nw][1]];
}
void dfs1(int now,int pre){
sz[now]=1;
Insert(trie1[now],trie1[pre],a[now]);
for(int i=head[now];i;i=nxt[i])
if(!dep[to[i]]){
dep[to[i]]=dep[now]+1;
fa[to[i]]=now;
dfs1(to[i],now);
sz[now]+=sz[to[i]];
if(!son[now]||sz[to[i]]>sz[son[now]])son[now]=to[i];
}
}
void dfs2(int now){
idfn[dfn[now]=++idx]=now;
if(son[now])top[son[now]]=top[now],dfs2(son[now]);
for(int i=head[now];i;i=nxt[i])
if(to[i]!=son[now]&&dep[to[i]]>dep[now])
dfs2(top[to[i]]=to[i]);
}
inline int LCA(int x,int y){
while(top[x]!=top[y])
if(dep[top[x]]>=dep[top[y]])x=fa[top[x]];else
y=fa[top[y]];
return dep[x]<dep[y]?x:y;
}
void query(int&R,int&L,int&num,int pp=30){
if(!~pp)return;
int nw=(num>>pp)&1^1;
if(siz[ch[R][nw]]>siz[ch[L][nw]]){
ans|=1<<pp;
query(ch[R][nw],ch[L][nw],num,pp-1);
}else
query(ch[R][!nw],ch[L][!nw],num,pp-1);
}
void query2(int&x,int&y,int&lca,int&fa,int&num,int pp=30){
if(!~pp)return;
int nw=(num>>pp)&1^1;
if(siz[ch[x][nw]]+siz[ch[y][nw]]-siz[ch[lca][nw]]-siz[ch[fa][nw]]>0){
ans|=1<<pp;
query2(ch[x][nw],ch[y][nw],ch[lca][nw],ch[fa][nw],num,pp-1);
}else
query2(ch[x][!nw],ch[y][!nw],ch[lca][!nw],ch[fa][!nw],num,pp-1);
}
int main(){
n=readint(),q=readint();
for(int i=1;i<=n;++i)a[i]=readint();
for(int i=1;i<n;++i){
int u=readint(),v=readint();
to[i<<1]=v;nxt[i<<1]=head[u];
head[u]=i<<1;
to[i<<1|1]=u;nxt[i<<1|1]=head[v];
head[v]=i<<1|1;
}
memset(dep,0,sizeof dep);
memset(son,0,sizeof son);
dep[1]=1;
dfs1(1,0);
dfs2(1);
for(int i=1;i<=n;++i)
Insert(trie2[i],trie2[i-1],a[idfn[i]]);
while(q--)
if(readint()==1){
int x=readint(),y=readint();
ans=0;query(trie2[dfn[x]+sz[x]-1],trie2[dfn[x]-1],y);
printf("%d\n",ans);
}else{
int x=readint(),y=readint(),z=readint();
int lca=LCA(x,y);
ans=0;
query2(trie1[x],trie1[y],trie1[lca],trie1[fa[lca]],z);
printf("%d\n",ans);
}
return 0;
}

  

[TJOI2018]xor的更多相关文章

  1. bzoj 5338: [TJOI2018]xor (树链剖分+可持久化01Trie)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5338 题面: 5338: [TJOI2018]xor Time Limit: 30 Sec  ...

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

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

  3. BZOJ5338[TJOI2018]xor——主席树+dfs序

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

  4. BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】

    题目分析: 很无聊的一道题目.首先区间内单点对应异或值的询问容易想到trie树.由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问.case2维护dfs序,对d ...

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

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

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

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

  7. [BZOJ5338][TJOI2018]xor

    bzoj luogu descirption 现在有一棵以 \(1\) 为根节点的由 \(n\) 个节点组成的树,树上每个节点上都有一个权值 \(v_i\) .现在有 \(Q\) 次操作,操作如下: ...

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

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

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

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

随机推荐

  1. 教你高速高效接入SDK——Unity统一接入渠道SDK(Android篇)

    U8SDK的设计之初,就是为了可以支持各种游戏引擎开发的游戏,而不不过Android的原生平台.眼下一大半的手游,都是採用Unity3D和Cocos2dx开发,那么这里,我们就先来一步步给大家演示,用 ...

  2. MySQL出现Ignoring query to other database的问题

    今天使用mysql的时候,输入随意一条命令都会出: Ignoring query to other database 这条错误信息,非常是奇怪. 后来才发现是登录数据库时.少了个-u的參数.. 正确的 ...

  3. h5-6 canvas

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 关于ShapeDrawable应用的一些介绍(上)

    在Android中, 很多时候系统原生的控件的格式并不能满足我们的需求,我们想要更加好看点的样式,像什么圆角矩形啊,颜色渐变啊,阴影效果啊等等的,这个时候就是我们的 ShapeDrawable发挥效果 ...

  5. bzoj5194: [Usaco2018 Feb]Snow Boots

    还真是.. 就是 一个被不点名批评的垃圾骗分暴力选手被普及难度的省选信心(??)模拟赛艹爆的题解 的t3嘛... #include<cstdio> #include<iostream ...

  6. Linux - 文件查找方法

    文件查找方法 1.which 查找可执行文件的位置 [root@local /]# which passwd /usr/bin/passwd 2.whereis 查找可执行文件的位置与相关的文件 [r ...

  7. poj 1018(枚举+贪心)

                                                                              通讯系统 We have received an o ...

  8. ubantu下NiFi单节点安装部署

    第一步,首先下载安装包:http://nifi.apache.org/download.html,博主下载的是1.4.0版本,直接下载的是编译后的文件. 第二步:将压缩包上传到服务器相应目录下,并且解 ...

  9. 关于Mybatis的几个问题

    今天在用mybatis开发的时候遇到两个问题,下面一一列出并给出解决方案. 问题一 最开始我设置的实体类中有个字段如isParent为boolean类型,set和get方法是eclispe自动生成的. ...

  10. mysql查询orderby

    --按某一字段分组取最大(小)值所在行的数据 /* 数据如下: name val memo a    2   a2(a的第二个值) a    1   a1--a的第一个值 a    3   a3:a的 ...