坑点是输入的t是数据组数编号,不用初始化,不是t组数据。。
主席树是动态开点线段树,当然可以不用离散化!当然时间复杂度没啥区别,不过空间复杂度++
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <math.h>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define endl '\n'
const int maxn = 2e5 + 5;
const int maxm = maxn << 1;
const int maxx = maxn * 100;
int head[maxn],nex[maxm],v[maxm],w[maxm],cnt,vis[maxn],dep[maxn];
void add(int x,int y){
nex[++cnt] = head[x];
head[x] = cnt;
v[cnt] = y;
}
int n,m,q,rt[maxn],val[maxx],ls[maxx],rs[maxx],idx,f[maxn],sz[maxn];
int a[maxn],fa[maxn][21],rooter;
int build(int l,int r){
int cur = ++idx;
val[cur] = 0;
if (l == r) return idx;
int mid = l + r >> 1;
ls[cur] = build(l,mid);
rs[cur] = build(mid + 1,r);
return cur;
}
int insert(int l,int r,int node,int p){
int cur = ++idx;
val[cur] = val[node] + 1,ls[cur] = ls[node],rs[cur] = rs[node];
if (l == r) return cur;
int mid = l + r >> 1;
if (p <= mid) ls[cur] = insert(l,mid,ls[cur],p);
else rs[cur] = insert(mid + 1,r,rs[cur],p);
return cur;
}
int query(int l,int r,int rt1,int rt2,int rt3,int rt4,int k){
if (l == r) return l;
int cur = val[ls[rt1]] + val[ls[rt2]] - val[ls[rt3]] - val[ls[rt4]];
int mid = l + r >> 1;
if (cur >= k) return query(l,mid,ls[rt1],ls[rt2],ls[rt3],ls[rt4],k);
return query(mid + 1,r,rs[rt1],rs[rt2],rs[rt3],rs[rt4],k - cur);
}
void dfs(int node,int father,int root){
fa[node][0] = father;
dep[node] = dep[father] + 1;
f[node] = root;
sz[root] ++;
vis[node] = 1;
for (int i = 1; i <= 20; ++i) {
fa[node][i] = fa[fa[node][i - 1]][i - 1];
}
rt[node] = insert(1,1e9,rt[father],a[node]);
for (int i = head[node]; i; i = nex[i]) {
int to = v[i];
if (to == father) continue;
dfs(to,node,root);
}
}
int lca(int x,int y){
if (dep[x] < dep[y]) swap(x,y);
for (int i = 20; i >= 0; --i) {
if (dep[fa[x][i]] >= dep[y]) x = fa[x][i];
}
if (x == y) return x;
for (int i = 20; i >= 0; --i) {
if (fa[x][i] != fa[y][i]) x = fa[x][i],y = fa[y][i];
}
return fa[x][0];
}
int find(int x){
if (x == f[x]) return x;
return f[x] = find(f[x]);
}
void solve(){
cin >> n >> m >> q;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
for (int i = 1; i <= m; ++i) {
int x,y;
cin >> x >> y;
add(x,y);
add(y,x);
}
for (int i = 1; i <= n; ++i) {
if (!vis[i]) dfs(i,0,i);
}
int lastans = 0;
while (q --){
char c;
int x,y,k;
cin >> c >> x >> y;
x ^= lastans;
y ^= lastans;
if (c == 'Q'){
cin >> k;
k ^= lastans;
int lc = lca(x,y),lcfa = fa[lc][0];
cout << (lastans = query(1,1e9,rt[x],rt[y],rt[lc],rt[lcfa],k)) << endl;
}
if (c == 'L'){
int fx = find(x),fy = find(y);
if (sz[fx] > sz[fy]){
swap(x,y);
swap(fx,fy);
}
add(x,y);
add(y,x);
dfs(x,y,fy);
}
}
}
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T = 1;
cin >> T;
solve();
}