原题:https://www.luogu.org/problemnew/show/P4592
题解:很明显如果是一个序列的话要用到Trie。树上操作时可以用树链剖分转化为序列形式,然后建Trie树就行了。其实就是两个版子。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct E{int to,nxt;}data[N<<1];
int cnt[N*35],ch[N*35][2],T[N];
int h[N],son[N],dep[N],father[N],id[N],top[N],wt[N],sz[N],a[N];
int n,m,len=1,num=0,tot=0;
inline int rd(){
int x=0;int f=1;char s=getchar();
while(!isdigit(s)) f=(s=='-'?-1:f),s=getchar();
while(isdigit(s)) x=(x<<1)+(x<<3)+s-'0',s=getchar();
return x*f;
}
inline void ins(int x,int y){
data[++len].to=y;data[len].nxt=h[x];h[x]=len;
data[++len].to=x;data[len].nxt=h[y];h[y]=len;
}
void dfs1(int x,int fa){
father[x]=fa;dep[x]=dep[fa]+1;sz[x]=1;
int maxson=-1;
for(int i=h[x];i;i=data[i].nxt){
int y=data[i].to;if(y==fa) continue;
dfs1(y,x);
sz[x]+=sz[y];
if(sz[y]>maxson) son[x]=y,maxson=sz[y];
}
}
void dfs2(int x,int tp){
id[x]=++num;top[x]=tp;wt[num]=a[x];
if(!son[x]) return ;
dfs2(son[x],tp);
for(int i=h[x];i;i=data[i].nxt){
int y=data[i].to;if(y==father[x] || y==son[x]) continue;
dfs2(y,y);
}
}
void ins(int aa,int b,int t,int x){
if(t<0) return ;
int i=(x>>t)&1;
ch[aa][!i]=ch[b][!i];
ch[aa][i]=++tot;
cnt[ch[aa][i]]=cnt[ch[b][i]]+1;
ins(ch[aa][i],ch[b][i],t-1,x);
}
int query(int aa,int b,int t,int x){
if(t<0) return 0;
int i=(x>>t)&1;
if(cnt[ch[b][!i]]>cnt[ch[aa][!i]]) return (1<<t)+query(ch[aa][!i],ch[b][!i],t-1,x);
else return query(ch[aa][i],ch[b][i],t-1,x);
}
void build(){
T[0]=++tot;ins(T[0],0,30,0);
for(int i=1;i<=n;i++) {
T[i]=++tot;ins(T[i],T[i-1],30,wt[i]);
}
}
inline int qson(int x,int y){
return query(T[id[x]-1],T[id[x]+sz[x]-1],30,y);
}
inline int qrange(int x,int y,int z){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans=max(ans,query(T[ id[top[x]]-1],T[id[x]],30,z));
x=father[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans=max(ans,query( T[id[x]-1],T[id[y]],30,z));
return ans;
}
int main(){
// freopen("xor.in","r",stdin);
n=rd();m=rd();
for(int i=1;i<=n;i++) a[i]=rd();
for(int i=1;i<n;i++){
int x=rd();int y=rd();
ins(x,y);
}
dep[0]=0;
dfs1(1,0);
dfs2(1,1);
build();
for(int i=1;i<=m;i++){
int opt=rd();int x=rd();int y=rd();int z;
if(opt==1){
printf("%d\n",qson(x,y));
}else{
z=rd();
printf("%d\n",qrange(x,y,z));
}
}
return 0;
}