题目
现在有一颗以1为根节点的由 n n n个节点组成的树,树上每个节点上都有一个权值 v i v_i vi。现在有 Q Q Q次操作,操作如下:
1
1
1
x
x
x
y
y
y:查询节点
x
x
x的子树中与
y
y
y异或结果的最大值
2
x
x
x
y
y
y
z
z
z:查询路径
x
x
x到
y
y
y上点与
z
z
z异或结果最大值
分析
这道题有两种操作,所以要分成两个可持久化01trie分别求解,其它其实有点类似最大异或和那道题,然而还要求LCA所以我就写了个树剖
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=100101;
struct node{int y,next;}e[N<<1];
int ls[N],rt1[N],rt2[N],tot,k=1,n,q,top[N],dfn[N],son[N],dep[N],a[N],fat[N],big[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct Trie{
int cnt[N<<6],trie[N<<6][2],tot;
inline void Insert(int &rt,int x,int now){
trie[++tot][0]=trie[rt][0],trie[tot][1]=trie[rt][1],cnt[tot]=cnt[rt]+1,rt=tot;
if (~now) Insert(trie[rt][(x>>now)&1],x,now-1);
}
inline signed query(int rt,int hs,int x,int now){
if (now==-1) return 0;
rr int p=((x>>now)&1)^1;
return cnt[trie[rt][p]]^cnt[trie[hs][p]]?query(trie[rt][p],trie[hs][p],x,now-1)|(1<<now):query(trie[rt][p^1],trie[hs][p^1],x,now-1);
}
}Tre;
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,fat[x]=fa,son[x]=1;
for (rr int i=ls[x],mson=-1;i;i=e[i].next)
if (e[i].y!=fa){
dfs1(e[i].y,x);
son[x]+=son[e[i].y];
if (son[e[i].y]>mson) big[x]=e[i].y,mson=son[e[i].y];
}
}
inline void dfs2(int x,int linp){
dfn[x]=++tot,top[x]=linp;
Tre.Insert(rt1[tot]=rt1[tot-1],a[x],29);
Tre.Insert(rt2[x]=rt2[fat[x]],a[x],29);
if (!big[x]) return; dfs2(big[x],linp);
for (rr int i=ls[x];i;i=e[i].next)
if (e[i].y!=fat[x]&&e[i].y!=big[x])
dfs2(e[i].y,e[i].y);
}
inline signed lca(int x,int y){
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) x^=y,y^=x,x^=y;
x=fat[top[x]];
}
if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
return x;
}
inline signed max(int a,int b){return a>b?a:b;}
signed main(){
n=iut(); q=iut(); Tre.tot=0;
for (rr int i=1;i<=n;++i) a[i]=iut();
for (rr int i=1;i<n;++i){
rr int x=iut(),y=iut();
e[++k]=(node){y,ls[x]},ls[x]=k,
e[++k]=(node){x,ls[y]},ls[y]=k;
}
dfs1(1,0),dfs2(1,1);
for (rr int i=1;i<=q;++i){
rr int opt=iut(),x=iut(),y=iut();
if (opt&1) print(Tre.query(rt1[dfn[x]+son[x]-1],rt1[dfn[x]-1],y,29));
else{
rr int z=iut(),Lca=lca(x,y);
print(max(Tre.query(rt2[x],rt2[fat[Lca]],z,29),Tre.query(rt2[y],rt2[fat[Lca]],z,29)));
}
putchar(10);
}
return 0;
}