洛谷P4592 [TJOI2018]异或 【可持久化trie树】

题目链接

BZOJ4592

题解

可持久化trie树裸题

写完就A了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 100005,B = 30,maxm = 5000005,INF = 1000000000;
inline int read(){
	int out = 0,flag = 1; char c = getchar();
	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
	return out * flag;
}
int bin[50];
struct Trie{
	int ch[maxm][2],sum[maxm],rt[maxn],cnt;
	int ins(int pre,int x){
		int tmp,u;
		tmp = u = ++cnt;
		for (int i = B; i >= 0; i--){
			ch[u][0] = ch[pre][0];
			ch[u][1] = ch[pre][1];
			sum[u] = sum[pre] + 1;
			int t = x & bin[i]; t >>= i;
			pre = ch[pre][t];
			u = ch[u][t] = ++cnt;
		}
		sum[u] = sum[pre] + 1;
		return tmp;
	}
	int query(int pre,int u,int x,int dep){
		if (dep < 0) return 0;
		int t = x & bin[dep]; t >>= dep;
		if (sum[ch[u][t ^ 1]] - sum[ch[pre][t ^ 1]])
			return bin[dep] + query(ch[pre][t ^ 1],ch[u][t ^ 1],x,dep - 1);
		return query(ch[pre][t],ch[u][t],x,dep - 1);
	}
	int Query(int a,int b,int c,int d,int x,int dep){
		if (dep < 0) return 0;
		int t = x & bin[dep]; t >>= dep;
		if (sum[ch[a][t ^ 1]] + sum[ch[b][t ^ 1]] - sum[ch[c][t ^ 1]] - sum[ch[d][t ^ 1]])
			return bin[dep] + Query(ch[a][t ^ 1],ch[b][t ^ 1],ch[c][t ^ 1],ch[d][t ^ 1],x,dep - 1);
		return Query(ch[a][t],ch[b][t],ch[c][t],ch[d][t],x,dep - 1);
	}
}T1,T2;
int n,Q,val[maxn];
int h[maxn],ne = 1;
struct EDGE{int to,nxt;}ed[maxn << 1];
inline void build(int u,int v){
	ed[++ne] = (EDGE){v,h[u]}; h[u] = ne;
	ed[++ne] = (EDGE){u,h[v]}; h[v] = ne;
}
int dfn[maxn],fa[maxn][18],at[maxn],siz[maxn],dep[maxn],cnt;
void dfs(int u){
	dfn[u] = ++cnt; at[cnt] = u; siz[u] = 1;
	T1.rt[u] = T1.ins(T1.rt[fa[u][0]],val[u]);
	REP(i,17) fa[u][i] =fa[fa[u][i - 1]][i - 1];
	Redge(u) if ((to = ed[k].to) != fa[u][0]){
		fa[to][0] = u; dep[to] = dep[u] + 1; dfs(to);
		siz[u] += siz[to];
	}
}
int lca(int u,int v){
	if (dep[u] < dep[v]) swap(u,v);
	for (int i = 0,d = dep[u] - dep[v]; (1 << i) <= d; i++)
		if (d & (1 << i)) u = fa[u][i];
	if (u == v) return u;
	for (int i = 17; i >= 0; i--)
		if (fa[u][i] != fa[v][i]){
			u = fa[u][i];
			v = fa[v][i];
		}
	return fa[u][0];
}
int main(){
	bin[0] = 1; REP(i,30) bin[i] = bin[i - 1] << 1;
	n = read(); Q = read();
	REP(i,n) val[i] = read();
	for (int i = 1; i < n; i++) build(read(),read());
	dfs(1);
	for (int i = 1; i <= n; i++)
		T2.rt[i] = T2.ins(T2.rt[i - 1],val[at[i]]);
	int opt,x,y,z,o;
	while (Q--){
		opt = read(); x = read(); y = read();
		if (opt & 1){
			printf("%d
",T2.query(T2.rt[dfn[x] - 1],T2.rt[dfn[x] + siz[x] - 1],y,B));
		}
		else {
			z = read(); o = lca(x,y);
			printf("%d
",T1.Query(T1.rt[x],T1.rt[y],T1.rt[o],T1.rt[fa[o][0]],z,B));
		}
	}
	return 0;
}

原文地址:https://www.cnblogs.com/Mychael/p/9049815.html