树剖上维护可持久化01trie即可
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<'='<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) // const int N=2e6+10; int T[N],Siz[N<<5],t[N<<5][2],ncnt; void upnode(int k,int val,int pre,int &pos) { pos=++ncnt; Siz[pos]=Siz[pre]+1; t[pos][0]=t[pre][0]; t[pos][1]=t[pre][1]; if(k<0)return ; int c=(val>>k)&1; upnode(k-1,val,t[pre][c],t[pos][c]); } int qmax(int k,int val,int pre,int pos) { if(k<0)return 0; int c=(val>>k)&1; int si=Siz[t[pos][c^1]]-Siz[t[pre][c^1]]; if(si)return (1<<k)+qmax(k-1,val,t[pre][c^1],t[pos][c^1]); else return qmax(k-1,val,t[pre][c],t[pos][c]); } int head[N],top[N],pos,id[N],tot,fa[N],dep[N],son[N],siz[N],n,m,node[N]; struct Edge{int to,nex;}edge[N<<1]; void add(int a,int b){edge[++pos]=(Edge){b,head[a]};head[a]=pos;} void dfs1(int x,int f) { fa[x]=f;dep[x]=dep[f]+1;siz[x]=1;son[x]=0; for(int i=head[x];i;i=edge[i].nex) { int v=edge[i].to; if(v==f)continue; dfs1(v,x);siz[x]+=siz[v]; if(siz[son[x]]<siz[v])son[x]=v; } } void dfs2(int x,int topf) { top[x]=topf;id[x]=++tot; upnode(30,node[x],T[tot-1],T[tot]); if(son[x])dfs2(son[x],topf); for(int i=head[x];i;i=edge[i].nex) { int v=edge[i].to;if(v==fa[x]||v==son[x])continue; dfs2(v,v); } } int Qmax(int x,int y,int val) { int ans=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]])swap(x,y); ans=max(ans,qmax(30,val,T[id[top[x]]-1],T[id[x]])); x=fa[top[x]]; } if(dep[x]>dep[y])swap(x,y); ans=max(ans,qmax(30,val,T[id[x]-1],T[id[y]])); return ans; } int main() { scanf("%d%d",&n,&m); rep(i,1,n) scanf("%d",&node[i]); rep(i,1,n-1) { int a,b;scanf("%d%d",&a,&b); add(a,b);add(b,a); } dfs1(1,0); dfs2(1,1);int x,y,z,op; while(m--) { scanf("%d",&op); if(op==1)scanf("%d%d",&x,&y),printf("%d\n",qmax(30,y,T[ id[x]-1 ],T[ id[x]+siz[x]-1 ] )); else scanf("%d%d%d",&x,&y,&z), printf("%d\n",Qmax(x,y,z)); } return 0; }