遇到水题了。贼嗨森。
题意简单,就不多解释了。
可持久化trie树模板*2,就A了。
第一棵树表示从根到该点,第二棵树依靠dfs序建立。然后就是注意空间问题,我想省一下空间,结果31层的树存不下,RE了3遍才找到,把31改成30就A了,,
#include<bits/stdc++.h> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<deque> #include<list> #include<set> #include<vector> #include<iostream> #define ll int #define re register #define inf 0x3f3f3f3f #define inl inline #define sqr(x) (x*x) //#define eps 1e-8 #define debug printf("debug "); //#pragma comment(linker, "/STACK:1024000000,1024000000") //#pragma GCC optimize (2) //#pragma G++ optimize (2) using namespace std; const ll mod=2520; const ll MAXN=1e5+10; const ll MAXM=(5e4+10)*4; inl ll read() { re ll x = 0; re int f = 1; char ch = getchar(); while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); } while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x * f; } inl char readc() { char ch=getchar(); while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar(); return ch; } inl void write(re ll x){ if(x>=10)write(x/10); putchar(x%10+'0'); } inl void writeln(re ll x){ if(x<0) {x=-x;putchar('-');} write(x); puts(""); } inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;} inl ll Lcm(re ll a,re ll b) {return a/gcd(a,b)*b;} inl void FR() { freopen(".in","r",stdin); freopen(".out","w",stdout); } inl void FC() { fclose(stdin); fclose(stdout); } struct edge { ll u,v,nxt; }e[MAXN<<1]; ll ssw[MAXN],n,cnt,head[MAXN],root1[MAXN],root2[MAXN]; inl void adde(ll u,ll v) { e[++cnt].u=u;e[cnt].v=v; e[cnt].nxt=head[u];head[u]=cnt; } ll T_cnt; struct Node { ll son[2],cnt; }Tree[100005<<6]; ll insert(ll pre,ll x) { re ll t=++T_cnt;Tree[t]=Tree[pre]; ll now=t;Tree[now].cnt++; for(re ll i=30;~i;i--) { if((x>>i)&1) { Tree[now].son[1]=++T_cnt; now=Tree[now].son[1]; pre=Tree[pre].son[1]; } else { Tree[now].son[0]=++T_cnt; now=Tree[now].son[0]; pre=Tree[pre].son[0]; } Tree[now]=Tree[pre];Tree[now].cnt++; } return t; } ll topn[MAXN],out[MAXN],d_tot,dfn[MAXN],f[MAXN][30],depth[MAXN]; void dfs(ll x,ll fa) { root1[x]=insert(root1[fa],ssw[x]); f[x][0]=fa;depth[x]=depth[fa]+1; for(re ll i=1;i<=25;i++) f[x][i]=f[f[x][i-1]][i-1]; topn[++d_tot]=x;dfn[x]=d_tot; for(re ll h=head[x];h;h=e[h].nxt) { re ll v=e[h].v; if(v==fa) continue ; dfs(v,x); } out[x]=d_tot; } ll lca(ll a,ll b) { if(depth[b]<depth[a]) swap(a,b); for(re ll i=25;~i;i--) { if(depth[f[b][i]]<depth[a]) continue ; b=f[b][i]; } if(a==b) return a; for(re ll i=25;~i;i--) { if(f[a][i]==f[b][i]) continue ; a=f[a][i],b=f[b][i]; } return f[a][0]; } ll query(ll l,ll r,ll x) { ll ans=0; for(re ll i=30;~i;i--) { ll p=(x>>i)&1; if(Tree[Tree[r].son[p^1]].cnt-Tree[Tree[l].son[p^1]].cnt) { l=Tree[l].son[p^1],r=Tree[r].son[p^1],ans|=(1<<i); } else { l=Tree[l].son[p],r=Tree[r].son[p]; } } return ans; } int main() { // FR(); n=read();re ll Q=read(); for(re ll i=1;i<=n;i++) ssw[i]=read(); for(re ll i=1;i<n;i++) { re ll u=read(),v=read(); adde(u,v);adde(v,u); } dfs(1,0); for(re ll i=1;i<=n;i++) {root2[topn[i]]=insert(root2[topn[i-1]],ssw[topn[i]]);} for(re ll i=1;i<=Q;i++) { re ll opt=read(); if(opt==1) { re ll x=read(),y=read(); writeln(query(root2[topn[dfn[x]-1]],root2[topn[out[x]]],y)); } else if(opt==2) { re ll x=read(),y=read(),z=read(); ll ssx=lca(x,y),ssy=f[ssx][0]; writeln(max(query(root1[ssy],root1[y],z),query(root1[ssy],root1[x],z))); } } // FC(); return 0; }