樹上可持久化trie的板子 第一棵樹按照dfs序建立 第二棵樹按照遍歷順序直接在父節點的基礎上建立
空間開N*50 開個N*30wa了 也不re de了半天bug
#include<bits/stdc++.h>
#define R register int
using namespace std;
const int N = 1e5+100;
int h[N],to[N<<1],nex[N<<1],cur,val[N],lg[N],fa[N][30],dep[N],tid[N],tt,siz[N],rk[N];
int n,q;
inline int in(){
R w=0,x=0;char c=0;
while(c>'9'||c<'0') w|=c=='-',c=getchar();
while(c<='9'&&c>='0') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return w?-x:x;
}
inline void add_edge(R x,R y){
to[++cur]=y;nex[cur]=h[x];h[x]=cur;
}
struct trie{
int ch[N*50][2],cnt[N*50],tot=0,rt[N];
void ins(R &o,R las,R t,R x){
o=++tot;cnt[o]=cnt[las]+1;
ch[o][1]=ch[las][1];ch[o][0]=ch[las][0];
if(t<0) return;
int c=(x>>t)&1;
ins(ch[o][c],ch[las][c],t-1,x);
}
void insert(R now,R pre,R val){
ins(rt[now],rt[pre],30,val);
}
int Q1(R ql,R qr,R t,R x){
if(t<0) return 0;
R c=(x>>t)&1;
if(cnt[ch[qr][c^1]]>cnt[ch[ql][c^1]]) return (1<<t)+Q1(ch[ql][c^1],ch[qr][c^1],t-1,x);
else return Q1(ch[ql][c],ch[qr][c],t-1,x);
}
int Q2(R a,R b,R c,R d,R t,R x){
if(t<0) return 0;
R e=(x>>t)&1;
if(cnt[ch[a][e^1]]+cnt[ch[b][e^1]]>cnt[ch[c][e^1]]+cnt[ch[d][e^1]])
return (1<<t)+Q2(ch[a][e^1],ch[b][e^1],ch[c][e^1],ch[d][e^1],t-1,x);
else return Q2(ch[a][e],ch[b][e],ch[c][e],ch[d][e],t-1,x);
}
}t1,t2;
void dfs(R u,R f){
dep[u]=dep[f]+1;fa[u][0]=f;tid[u]=++tt;rk[tt]=u;siz[u]=1;
t2.insert(u,f,val[u]);
for(R i = 1; i <= lg[dep[u]]; i++) fa[u][i]=fa[fa[u][i-1]][i-1];
for(R i = h[u]; i; i = nex[i])
if(to[i]!=f) dfs(to[i],u),siz[u]+=siz[to[i]];
}
inline int lca(R x,R y){
if(dep[x]<dep[y]) swap(x,y);
while(dep[x]>dep[y]) x=fa[x][lg[dep[x]-dep[y]]-1];
if(x==y) return x;
for(R i = lg[dep[x]-1]; i >= 0; i--)
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int main(){
n=in(),q=in();
for(R i = 1; i <= n; i++) val[i]=in(),lg[i]=(1<<lg[i-1]==i)+lg[i-1];
for(R i = 1; i <= n-1; i++){
R u,v;
u=in(),v=in();
add_edge(u,v);add_edge(v,u);
}
dfs(1,0);
for(R i = 1; i <= n; i++)
t1.insert(i,i-1,val[rk[i]]);
for(R i = 1; i <= q; i++){
R op,x,y,z;
op=in();x=in();y=in();
if(op==1){
//printf("tid[%d]=%d siz[%d]=%d\n",x,tid[x],x,siz[x]);
printf("%d\n",t1.Q1(t1.rt[tid[x]-1],t1.rt[tid[x]+siz[x]-1],30,y));
}else{
z=in();
int lcax=lca(x,y);
printf("%d\n",t2.Q2(t2.rt[x],t2.rt[y],t2.rt[lcax],t2.rt[fa[lcax][0]],30,z));
}
}
return 0;
}