LOJ#6038. 「雅礼集训 2017 Day5」远行 题解
在并查集上维护每个联通块的直径,同时用 \(LCT\) 维护树形态即可。
\(\Theta((n+m)\log n)\)
code :
#include <bits/stdc++.h>
using namespace std;
template <typename T> void read(T &x){
x = 0; char ch = getchar();
while (!isdigit(ch)) ch = getchar();
while (isdigit(ch)) x = x * 10 + ch - '0',ch = getchar();
}
inline void write(int x){if (x > 9) write(x/10); putchar(x%10+'0'); }
const int N = 300005,Q = 500005;
struct Link_Cut_Tree{
int s[2][N],fa[N],rev[N],siz[N];
inline bool nrt(int x){ return x == s[0][fa[x]] || x == s[1][fa[x]]; }
inline bool pos(int x){ return x == s[1][fa[x]]; }
inline void up(int o){ siz[o] = siz[s[0][o]] + siz[s[1][o]] + 1; }
inline void down(int o){
if (rev[o]){
swap(s[0][o],s[1][o]),rev[o] = 0;
if (s[0][o]) rev[s[0][o]] ^= 1; if (s[1][o]) rev[s[1][o]] ^= 1;
}
}
inline void downall(int o){ if (nrt(o)) downall(fa[o]); down(o); }
inline void rotate(int x){
static int y,p; y = fa[x],p = pos(x);
fa[x] = fa[y]; if (nrt(y)) s[pos(y)][fa[y]] = x;
s[p][y] = s[!p][x]; if (s[p][y]) fa[s[p][y]] = y; s[!p][x] = y,fa[y] = x; up(y),up(x);
}
inline void splay(int x){ downall(x); while (nrt(x)){ if (nrt(fa[x])) rotate((pos(x) ^ pos(fa[x])) ? x : fa[x]); rotate(x); } }
inline void access(int x){ static int y; for (y = 0; x ; y = x,x = fa[x]) splay(x),s[1][x] = y,up(x); }
inline void makeroot(int x){ access(x),splay(x),rev[x] ^= 1,down(x); }
inline void link(int x,int y){ makeroot(x),fa[x] = y; }
inline int query(int x,int y){ makeroot(x),access(y),splay(y); return siz[y] - 1; }
}T;
struct Node{
int u,v,d;
inline void adjust(int x){
if ((u^v) && T.query(x,u) < T.query(x,v)) swap(u,v);
}
};
Node operator + (Node a,Node b){
static Node tmp; static int l;
tmp = (a.d > b.d) ? a : b;
if ((l = T.query(a.u,b.u)) > tmp.d) tmp.d = l,tmp.u = a.u,tmp.v = b.u;
return tmp;
}
struct Union_Find_Set{
int fa[N]; Node v[N];
inline void init(int n){ for (int i = 1; i <= n; ++i) fa[i] = v[i].u = v[i].v = i,v[i].d = 0; }
inline int Find(int x){ return x == fa[x] ? x : (fa[x] = Find(fa[x])); }
inline void Link(int x,int y){
T.link(x,y),v[Find(x)].adjust(x),v[Find(y)].adjust(y);
x = fa[x],y = fa[y],fa[x] = y,v[y] = v[x] + v[y];
}
inline int query(int x){
static int y; y = Find(x);
return max(T.query(x,v[y].u),T.query(x,v[y].v));
}
}S;
int ans,type,n,q,op,x,y;
int main(){
read(type),read(n),read(q),S.init(n);
while (q--){
read(op),read(x); if (op == 1) read(y);
if (type) x ^= ans,y ^= ans;
if (op == 1) S.Link(x,y); else write(ans = S.query(x)),putchar('\n');
}
return 0;
}