P4592 [TJOI2018]异或
本人新学(自行脑补)可持久化\(\text{01trie}\),敲个板子。
毫无思维但真心难调。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
int n,m,a[maxn];
int beg[maxn],nex[maxn<<1],to[maxn<<1],e;
inline void add(int x,int y){
e++;nex[e]=beg[x];
beg[x]=e;to[e]=y;
}
int fa[maxn],dfn[maxn],siz[maxn],ti,f[maxn][20],dep[maxn];
struct trie{
int rt[maxn],ch[maxn*100][2],val[maxn*100],cnt;
inline int insert(int rt1,int rt2,int x){
int res=cnt+1;rt1=++cnt;
for(int i=30;i>=0;i--){
val[rt1]=val[rt2]+1;
ch[rt1][0]=ch[rt2][0];
ch[rt1][1]=ch[rt2][1];
int t=(x>>i&1);
rt1=ch[rt1][t]=++cnt;
rt2=ch[rt2][t];
}val[rt1]=val[rt2]+1;
return res;
}
inline int query1(int rt1,int rt2,int x){
int res=0;
for(int i=30;i>=0;i--){
int t=(x>>i&1);
if(val[ch[rt1][!t]]>val[ch[rt2][!t]]){
res|=(1<<i);
rt1=ch[rt1][!t];
rt2=ch[rt2][!t];
}else{
rt1=ch[rt1][t];
rt2=ch[rt2][t];
}
}
return res;
}
inline int query2(int rt1,int rt2,int rt3,int rt4,int x){
int res=0;
for(int i=30;i>=0;i--){
int t=(x>>i&1);
if(val[ch[rt1][!t]]+val[ch[rt2][!t]]>val[ch[rt3][!t]]+val[ch[rt4][!t]]){
res|=(1<<i);
rt1=ch[rt1][!t];rt2=ch[rt2][!t];
rt3=ch[rt3][!t];rt4=ch[rt4][!t];
}else{
rt1=ch[rt1][t];rt2=ch[rt2][t];
rt3=ch[rt3][t];rt4=ch[rt4][t];
}
}
return res;
}
}tr1,tr2;
inline int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=19;~i;--i)
if(dep[f[x][i]]>=dep[y])x=f[x][i];
if(x==y)return x;
for(int i=19;~i;--i)
if(f[x][i]!=f[y][i]){
x=f[x][i];
y=f[y][i];
}
return f[x][0];
}
inline void dfs(int x,int anc){
fa[x]=anc;dfn[x]=++ti;siz[x]=1;dep[x]=dep[anc]+1;
tr1.rt[ti]=tr1.insert(tr1.rt[ti],tr1.rt[ti-1],a[x]);
tr2.rt[x]=tr2.insert(tr2.rt[x],tr2.rt[anc],a[x]);
f[x][0]=anc;for(int i=1;i<=19;i++)f[x][i]=f[f[x][i-1]][i-1];
for(int i=beg[x];i;i=nex[i])
if(to[i]!=anc)dfs(to[i],x),siz[x]+=siz[to[i]];
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++)
a[i]=read();
int opt,x,y,z,t;
for(int i=1;i<n;i++){
x=read(),y=read();
add(x,y),add(y,x);
}
dfs(1,0);
for(int i=1;i<=m;i++){
opt=read();
if(opt==1){
x=read(),z=read();
printf("%d\n",tr1.query1(tr1.rt[dfn[x]+siz[x]-1],tr1.rt[dfn[x]-1],z));
}else{
x=read(),y=read(),z=read();
t=lca(x,y);
printf("%d\n",tr2.query2(tr2.rt[x],tr2.rt[y],tr2.rt[t],tr2.rt[fa[t]],z));
}
}
return 0;
}
深深地感到自己的弱小。