P4592 [TJOI2018]異或 樹上可持久化trie

樹上可持久化trie的板子 第一棵樹按照dfs序建立 第二棵樹按照遍歷順序直接在父節點的基礎上建立  

空間開N*50 開個N*30wa了 也不re de了半天bug

#include<bits/stdc++.h>
#define R register int
using namespace std;
const int N = 1e5+100;
int h[N],to[N<<1],nex[N<<1],cur,val[N],lg[N],fa[N][30],dep[N],tid[N],tt,siz[N],rk[N];
int n,q;
inline int in(){
	R w=0,x=0;char c=0;
	while(c>'9'||c<'0') w|=c=='-',c=getchar();
	while(c<='9'&&c>='0') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return w?-x:x; 
}
inline void add_edge(R x,R y){
	to[++cur]=y;nex[cur]=h[x];h[x]=cur;
}
struct trie{
	int ch[N*50][2],cnt[N*50],tot=0,rt[N];
	void ins(R &o,R las,R t,R x){
		o=++tot;cnt[o]=cnt[las]+1;
		ch[o][1]=ch[las][1];ch[o][0]=ch[las][0]; 
		if(t<0) return;
		int c=(x>>t)&1;
		ins(ch[o][c],ch[las][c],t-1,x);
	}
	void insert(R now,R pre,R val){
		ins(rt[now],rt[pre],30,val);
	}
	int Q1(R ql,R qr,R t,R x){
		if(t<0) return 0;
		R c=(x>>t)&1;
		if(cnt[ch[qr][c^1]]>cnt[ch[ql][c^1]]) return (1<<t)+Q1(ch[ql][c^1],ch[qr][c^1],t-1,x);
		else return Q1(ch[ql][c],ch[qr][c],t-1,x);
	}
	int Q2(R a,R b,R c,R d,R t,R x){
		if(t<0) return 0;
		R e=(x>>t)&1;
		if(cnt[ch[a][e^1]]+cnt[ch[b][e^1]]>cnt[ch[c][e^1]]+cnt[ch[d][e^1]])
		return (1<<t)+Q2(ch[a][e^1],ch[b][e^1],ch[c][e^1],ch[d][e^1],t-1,x);
		else return Q2(ch[a][e],ch[b][e],ch[c][e],ch[d][e],t-1,x);
	}
}t1,t2;
void dfs(R u,R f){
	dep[u]=dep[f]+1;fa[u][0]=f;tid[u]=++tt;rk[tt]=u;siz[u]=1;
	t2.insert(u,f,val[u]);
	for(R i = 1; i <= lg[dep[u]]; i++) fa[u][i]=fa[fa[u][i-1]][i-1];
	for(R i = h[u]; i; i = nex[i])
		if(to[i]!=f) dfs(to[i],u),siz[u]+=siz[to[i]];
}
inline int lca(R x,R y){
	if(dep[x]<dep[y]) swap(x,y);
	while(dep[x]>dep[y]) x=fa[x][lg[dep[x]-dep[y]]-1];
	if(x==y) return x;
	for(R i = lg[dep[x]-1]; i >= 0; i--)
	if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}
int main(){
	n=in(),q=in();
	for(R i = 1; i <= n; i++) val[i]=in(),lg[i]=(1<<lg[i-1]==i)+lg[i-1];
	for(R i = 1; i <= n-1; i++){
		R u,v;
		u=in(),v=in();
		add_edge(u,v);add_edge(v,u);
	} 
	dfs(1,0);
	for(R i = 1; i <= n; i++)
	t1.insert(i,i-1,val[rk[i]]);
	for(R i = 1; i <= q; i++){
		R op,x,y,z;
		op=in();x=in();y=in();
		if(op==1){
			//printf("tid[%d]=%d siz[%d]=%d\n",x,tid[x],x,siz[x]);
			printf("%d\n",t1.Q1(t1.rt[tid[x]-1],t1.rt[tid[x]+siz[x]-1],30,y));
		}else{
			z=in();
			int lcax=lca(x,y);
			printf("%d\n",t2.Q2(t2.rt[x],t2.rt[y],t2.rt[lcax],t2.rt[fa[lcax][0]],30,z));
		}
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章