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;
}

深深地感到自己的弱小。

posted @ 2021-02-19 01:09  syzf2222  阅读(23)  评论(0编辑  收藏  举报