SOL: 我们可以树剖,对dfs序建可持久trie。
#include<bits/stdc++.h> #define sight(x) ('0'<=x&&x<='9') #define eho(x) for(int i=head[x];i;i=net[i]) #define v fall[i] #define N 7000007 #define M 200007 //#define 30 4 int siz[M],son[M],sss[N],s[N][2],tot,tog,tim,ans,n,m,p[N]; int be[N],ed[N],fall[N<<1],net[N<<1],head[N],dep[N],f[N],top[N]; using namespace std; inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } inline void adds(int x,int y){ fall[++tot]=y; net[tot]=head[x]; head[x]=tot; fall[++tot]=x; net[tot]=head[y]; head[y]=tot; } void dfs(int x,int fa){ siz[x]=1; eho(x) if (v^fa) { dfs(v,x); siz[x]+=siz[v]; if (siz[son[x]]<siz[v]) son[x]=v; } } int ds[M]; void dfs2(int x,int fa){ dep[x]=dep[fa]+1; f[x]=fa; be[x]=++tim; ds[tim]=x; if (son[x]) top[son[x]]=top[x],dfs2(son[x],x); eho(x) if (v^fa&&v^son[x]) top[v]=v,dfs2(v,x); ed[x]=tim; } void add(int past,int now,int len,int key){ sss[now]=sss[past]+1; if (len==-1) {return; } if ((key>>len)&1) { s[now][0]=s[past][0]; s[now][1]=++tog; add(s[past][1],tog,len-1,key); } else { s[now][1]=s[past][1]; s[now][0]=++tog; add(s[past][0],tog,len-1,key); } } void query(int past,int now,int len,int key){ if (len==-1) return; assert(sss[now]>0); if ((((key>>len)&1)==1)&&(sss[s[now][0]]-sss[s[past][0]]>0) ||(((key>>len)&1)==0)&&(sss[s[now][1]]-sss[s[past][1]]==0)) { query(s[past][0],s[now][0],len-1,key); } else { query(s[past][1],s[now][1],len-1,key); ans+=1<<len; } } int x,y,z,op,ox; signed main () { read(n); read(m); for (int i=1;i<=n;i++) read(p[i]); for (int i=1;i< n;i++) read(x),read(y),adds(x,y); dfs(1,0); top[1]=1; dfs2(1,0); tog=n; for (int i=1;i<=n;i++) add(i-1,i,31,p[ds[i]]); while (m--) { read(op); if (op==1) { read(x);read(y); ans=0; query(be[x]-1,ed[x],31,y); writeln(y^ans); } if (op==2) { ox=0; read(x); read(y); read(z); while (top[x]^top[y]) { ans=0; if (dep[top[x]]<dep[top[y]]) swap(x,y); query(be[top[x]]-1,be[x],31,z); x=f[top[x]]; ox=max(ox,ans^z); } if (be[x]>be[y]) swap(x,y); ans=0; query(be[x]-1,be[y],31,z); ox=max(ox,ans^z); writeln(ox); } } return 0; }