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;
}
posted @ 2020-09-04 22:27  srf  阅读(140)  评论(0编辑  收藏  举报