How-many

#include <bits/stdc++.h>
using namespace std ; 
const int N = 2e5 ; 
inline int read() {
	int x = 0 , f = 1 ; 
	char c = getchar() ; 
	
	while (c < '0' ||  c > '9') {
		if (c == '-') f = -f ; 
		
		c = getchar() ; 
	}
	
	while (c >= '0' && c <= '9') {
		x = x * 10 + c - '0' ; 
		c = getchar() ; 
	}
	
	return x * f ; 
} 

#ifndef Scapegoat_Tree
#define lson(x) t[x].son[0]
#define rson(x) t[x].son[1]
#define Size(x) t[x].Size
#define value(x) t[x].value
#define Cnt(x) t[x].cnt
struct _Point {
	int son[2] , Size , value ; 
	int cnt ; 
} t[N * 45] ; 

int numbol ; int tot , chain[N] ; 
const double alpha = 0.75 ; 

void Getchain(int x) {
	if (!x) return ; 
	if (t[x].cnt) chain[++ tot] = x ; 

	Getchain(lson(x)) , Getchain(rson(x)) ; 
}

inline void push_up(int x) {
	t[x].Size = Size(lson(x)) + Size(rson(x)) + Cnt(x) ; 
}

int build(int l , int r) {
	if (l == r) return 0 ; 

	int mid = (l + r) >> 1 ; 
	lson(chain[mid]) = build(l , mid) ; 
	rson(chain[mid]) = build(mid + 1 , r) ; 
	push_up(chain[mid]) ; 
	return chain[mid] ; 
}

void check(int x) {
	if (Size(x) * alpha < max(Size(lson(x)) , Size(rson(x)))) {
		tot = 0 ; Getchain(x) ; 
		build(1 , tot + 1) ; 
	}
}

void Insert(int &x , int val) {
	if (!x) {
		x = ++ numbol ; 
		Cnt(x) = 1 ; Size(x) = 1 ; value(x) = val ; 
		return ; 
	} else if (value(x) == val) return ++ Cnt(x) , void() ; 

	if (value(x) > val) Insert(lson(x) , val) ; 
	else Insert(rson(x) , val) ; 
	push_up(x) ; check(x) ; 
}

void Erase(int &x , int val) {
	Size(x) -- ; 

	if (value(x) == val) return -- Cnt(x) , void() ; 
	else if (value(x) > val) Erase(lson(x) , val) ; 
	else Erase(rson(x) , val) ; 
	push_up(x) ; check(x) ; 
}

int Find(int x , int k) {
	while (114514) {
		if (k <= Cnt(x) + Size(lson(x))) return value(x) ; 
		else if (Size(lson(x)) >= k) x = lson(x) ; 
		else k -= Cnt(x) + Size(lson(x)) , x = rson(x) ; 
	}
}

#undef lson
#undef rson
#undef value
#undef Size
#endif

#ifndef SEGMENT_TREE
#define lson (id << 1)
#define rson (id << 1 | 1)
#define mid ((l + r) >> 1)
int ts[N << 2] ; 

void updata(int id , int l , int r , int x , int c) {
	if (l == r) return ts[id] = c , void() ; 

	if (x <= mid) updata(lson , l , mid , x , c) ; 
	else updata(rson , mid + 1 , r , x , c) ; 

	ts[id] = max(ts[lson] , ts[rson]) ; 
}

#undef lson
#undef rson
#undef mid
#endif

int n , m , Size[N] , top[N] , son[N] , heavy[N] , depth[N] ; 
int root ; bool vis[N] , color[N] ; int all[N] , s[N] , father[N] ; 

struct EGDE {
	int next , to ; 
} e[N << 1] , e1[N << 1] ; int head[N] , head1[N] , cnt1 , cnt ; 
inline void add(int x , int y) {
	cnt ++ ; e[cnt].next = head[x] , e[cnt].to = y , head[x] = cnt ; 
}
inline void add1(int x , int y) {
	cnt1 ++ ; e1[cnt1].next = head1[x] , e[cnt1].to = y ; head1[x] = cnt1 ; 
}

inline int LCA(int x , int y) {
	int topper_x = top[x] , topper_y = top[y] ; 

	while (topper_x != topper_y) {
		if (depth[topper_x] >= depth[topper_y]) {
			x = father[topper_x] ; 
		} else y = father[topper_y] ; 
	}

	return depth[x] >= depth[y] ? y : x ; 
}

inline int dis(int x , int y) {
	return depth[x] + depth[y] - 2 * depth[LCA(x , y)] ; 
}

void dfs1(int x , int fa) {
	Size[x] = 1 ; son[x] = 0 ; 
	
	for (int i = head[x] ; i ; i = e[i].next) {
		int y = e[i].to ; 

		if (y != fa && !vis[y]) {
			dfs1(y , x) , Size[x] += Size[y] ; 
			son[x] = max(son[x] , Size[y]) ; 
		}
	}

	son[x] = max(son[x] , Tree_Size - Size[x]) ; 

	if (son[x] < son[root]) root = x ; 
}

void dfs_dep(int x , int fa) {
	depth[x] = depth[fa] + 1 ; 

	for (int i = head[x] ; i ; i = e[i].next) {
		int y = e[i].to ; 

		if (y != fa) {
			dfs_dep(y , x) ; 

			if (Size[y] > Size[heavy[x]]) heavy[x] = y ; 
		}
	}
}

void dfs_top(int x , int crown) {
	top[x] = crown ; 

	if (heavy[x]) dfs_top(heavy[x] , crown) ; 

	for (int i = head[x] ; i ; i = e[i].next) {
		int y = e[i].to ; 

		if (y != fa && y != heavy[x])
			dfs_top(y , y) ; 
	}
}

void dfs_build(int x) {
	vis[x] = 1 ; 

	for (int i = head[x] ; i ; i = e[i].next) {
		int y = e[i].to ; 

		if (!vis[y]) {
			root = 0 ; dfs1(y , 0) ; father[root] = x ; 
			add1(x , root) ; dfs_build(root) ; 
		}
	}
}

void dfs_goat(int x , int now) {
	Insert(all[now] , dis(now , x)) ; 

	for (int i = head1[x] ; i ; i = e[i].next) {
		int y = e1[i].to ; 
		dfs_goat(y , now) ; 
	}
}

void dfs_set(int x) {
	for (int i = head1[x] ; i ; i = e1[i].next) {
		int y = e1[i].to ; 
		dfs_goat(y , x) , dfs_set(y) ; 
		Insert(s[x] , Find(all[y] , Size(all[y]))) ; 
	}

	Insert(s[x] , 0) , Insert(all[x] , 0) ; 
}

void Delete(int x , int pos) {
	if (!x) return ; 

	int last = Find(all[x] , Size(all[x])) ; 
	Erase(all[x] , dis(x , pos)) ; 
	int now = Find(all[x] , Size(all[x])) ; 

	if (father[x]) {
		int fa = father[x] ; 
		Erase(s[fa] , last) ; Insert(s[fa] , now) ; 
	}

	if (Size(all[x])) {
		updata(1 , 1 , n , x , Find(s[x] , Size(s[x])) + Find(s[x] , Size(s[x]) - 1)) ; 
	} else updata(1 , 1 , n , x , 0) ; 

	Delete(father[x] , pos) ; 
}

void Modify(int x , int pos) {
	if (!x) return ; 

	int last = Find(all[x] , Size(all[x])) ; 
	Insert(all[x] , dis(x , pos)) ; 
	int now = Find(all[x] , Size(all[x])) ; 

	if (father[x]) {
		int fa = father[x] ; 
		Erase(s[fa] , last) , Insert(s[fa] , now) ; 
	}

	updata(1 , 1 , n , x , Find(s[x] , Size(s[x])) + Find(s[x] , Size(s[x]) - 1)) ; 
	Modify(father[x] , pos) ; 
}

char opt ; int num ; 

signed main() {
	#ifndef ONLINE_JUDGE
		freopen("1.in" , "r" , stdin) ; 
		freopen("1.out" , "w" , stdout) ; 
	#endif
	n = read() , num = n ; 
	
	for (int i = 1 , x , y ; i < n ; ++ i) {
		x = read() , y = read() ; 
		add(x , y) , add(y , x) ; 
	}

	auto Getcher = []() {
		char c = getchar() ; 
		while (c != 'G' && c != 'C') c = getchar() ; 
		return c ; 
	} ; 

	dfs_dep(1 , 0) ; dfs_top(1 , 1) ; 
	root = 0 ; son[0] = 0x7f7f7f7f ; 
	dfs1(1 , 0) ; dfs_build(root) ; 
	m = read() ; int x ; 

	while (m --) {
		opt = read() ; 

		if (opt == 'C') {
			x = read() , color[x] ^= 1 ; 

			if (color[x]) {
				num -- ; 
				Delete(x , x) ; 
			} else {
				num ++ ; 
				Modify(x , x) ; 
			}
		} else {
			if (!num) cout << -1 << '\n' ; 
			else if (num == 1) cout << 0 << '\n' ; 
			else cout << ts[1] << '\n' ; 
		}
	}
}
posted @ 2024-07-05 11:12  HANGRY_Sol&Cekas  阅读(7)  评论(0编辑  收藏  举报