P4592 [TJOI2018] 异或
Sol
直接建立两颗可持久化线段树,一个维护以 dfn 为下标的数,这个是为了做子树异或,一个做根到当前点的,这个是为了做链上异或。
Code
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define pf push_front
#define desktop "C:\\Users\\incra\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
if (y > x) return x = y,true;
return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
if (y < x) return x = y,true;
return false;
}
LL power (LL a,LL b,LL p) {
LL ans = 1;
while (b) {
if (b & 1) ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 100010,MAX_LOG = 20,M = 2 * 32 * N;
int n,q;
int a[N];
vector <int> g[N];
int rt1[N],rt2[N];
int tr[M][2],s[M],idx;
int dfn[N],last[N],timestamp;
int f[N][MAX_LOG];
int dep[N];
int clone (int u) {
idx++;
tr[idx][0] = tr[u][0];
tr[idx][1] = tr[u][1];
s[idx] = s[u];
return idx;
}
void insert (int &u,int x,int i) {
u = clone (u);
s[u]++;
if (~i) insert (tr[u][x >> i & 1],x,i - 1);
}
void DFS (int u,int fa) {
dfn[u] = ++timestamp;
dep[u] = dep[fa] + 1;
insert (rt1[dfn[u]] = rt1[dfn[u] - 1],a[u],30);
insert (rt2[u] = rt2[fa],a[u],30);
for (int v : g[u]) {
if (v == fa) continue;
f[v][0] = u;
for (int i = 1;i < MAX_LOG;i++) f[v][i] = f[f[v][i - 1]][i - 1];
DFS (v,u);
}
last[u] = timestamp;
}
int get_LCA (int a,int b) {
if (dep[a] < dep[b]) swap (a,b);
for (int i = MAX_LOG - 1;i >= 0;i--) {
if (dep[f[a][i]] >= dep[b]) a = f[a][i];
}
if (a == b) return a;
for (int i = MAX_LOG - 1;i >= 0;i--) {
if (f[a][i] == f[b][i]) continue;
a = f[a][i],b = f[b][i];
}
return f[a][0];
}
int query (int u,int v,int x,int i) {
if (i == -1) return 0;
int t = x >> i & 1;
if (s[tr[u][!t]] - s[tr[v][!t]]) return query (tr[u][!t],tr[v][!t],x,i - 1) + (1 << i);
return query (tr[u][t],tr[v][t],x,i - 1);
}
void mian () {
cin >> n >> q;
for (int i = 1;i <= n;i++) cin >> a[i];
for (int i = 1;i < n;i++) {
int a,b;
cin >> a >> b;
g[a].pb (b),g[b].pb (a);
}
DFS (1,0);
while (q--) {
int op;
cin >> op;
if (op == 1) {
int a,b;
cin >> a >> b;
cout << query (rt1[last[a]],rt1[dfn[a] - 1],b,30) << endl;
}
else {
int a,b,c;
cin >> a >> b >> c;
int p = f[get_LCA (a,b)][0];
cout << max (query (rt2[a],rt2[p],c,30),query (rt2[b],rt2[p],c,30)) << endl;
}
}
}
int main () {
int T = 1;
// cin >> T;
while (T--) mian ();
return 0;
}

浙公网安备 33010602011771号