题目链接

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\n",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\n",T1.Query(T1.rt[x],T1.rt[y],T1.rt[o],T1.rt[fa[o][0]],z,B));
}
}
return 0;
}
05-11 19:26