僞Top-Tree——[Bjoi2014]大融合(bzoj4530)

樸素的LCT是不維護虛邊以及輕兒子的。

但是這道題需要動態維護這麼一個子樹大小,就可以考慮維護一下虛邊。

一個節點x,維護兩個:虛兒子的子樹大小之和,以及整棵子樹大小。

然後這題就結束了。注意long long。

這輩子都不可能寫真正的top-tree的。只能寫寫僞top-tree這樣來維持一下生計。

#include <cstdio>
#include <algorithm>
#define N 100010
#define pa fa[x]
#define lc ch[x][0]
#define rc ch[x][1]
using namespace std;
inline char gc() {
	static char now[1<<16], *S, *T;
	if(S == T) {T = (S = now) + fread(now, 1, 1<<16, stdin); if(S == T) return EOF;}
	return *S++;
}
inline int read() {
	int x = 0; char c = gc();
	while(c < '0' || c > '9') c = gc();
	while(c >= '0' && c <= '9') {x = x * 10 + c - 48; c = gc();}
	return x;
}
int ch[N][2], fa[N], sz[N], sum[N], rev[N];
inline void update(int x) {sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + sz[x] + 1;}
inline void rever(int x) {rev[x]^= 1; swap(ch[x][0], ch[x][1]);}
inline void pushdown(int x) {
	if(rev[x]) {
		if(lc) rever(lc);
		if(rc) rever(rc);
		rev[x] = 0;
	}
}
inline bool isr(int x) {return ch[pa][0] != x && ch[pa][1] != x;}
void pd(int x) {if(!isr(x)) pd(pa); pushdown(x);}
inline bool wh(int x) {return ch[pa][1] == x;}
inline void rotate(int x) {
	int y = fa[x], z = fa[y], c = wh(x);
	if(!isr(y)) ch[z][wh(y)] = x;
	fa[x] = z;
	ch[y][c] = ch[x][c^1]; fa[ch[x][c^1]] = y;
	ch[x][c^1] = y; fa[y] = x;
	update(y); update(x);
}
inline void splay(int x) {
	pd(x);
	for(; !isr(x); rotate(x))
		if(!isr(pa)) rotate(wh(pa) == wh(x) ? pa : x);
}
inline void access(int x) {
	for(int y = 0; x; y = x, x = pa) {
		splay(x);
		sz[x]+= sum[rc] - sum[y];
		rc = y, update(x);
	}
}
inline void maker(int x) {
	access(x); splay(x); rever(x);
}
inline void link(int x, int y) {
	maker(x); access(y); splay(y);
	fa[x] = y; sz[y]+= sum[x]; update(y);
}
int n, q;
int main() {
	n = read(); q = read();
	for(int i = 1; i <= n; ++i) sum[i] = 1;
	for(int i = 1; i <= q; ++i) {
		char opt = gc(); while(opt != 'A' && opt != 'Q') opt = gc(); int x = read(), y = read();
		if(opt == 'A') link(x, y);
		else {maker(x); access(y); splay(x); printf("%lld\n", (long long)sum[y] * (sum[x] - sum[y]));}
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章