• 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('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    TV
    [转载]如果看了这篇文章你还不懂傅里叶变换,那就过来掐死我吧
    search result
    floating-camera
    HDU 1032.The 3n + 1 problem【注意细节】【预计数据不强】【8月21】
    C语言socket send()数据缓存问题
    Marlin固件之—:基础入门与測试
    java语句顺序有时非常重要
    Android Studio 使用正式签名进行调试
    插入排序、交换排序、选择排序、归并排序、基数排序
  • 原文地址:https://www.cnblogs.com/s-r-f/p/13616517.html
Copyright © 2020-2023  润新知