记录编号 218551 评测结果 AAAAAAAAAT
题目名称 [ZJOI 2007]捉迷藏 最终得分 90
用户昵称 Gravatarlyxin65 是否通过 未通过
代码语言 C++ 运行时间 9.757 s
提交时间 2016-01-09 23:57:08 内存使用 24.44 MiB
显示代码纯文本
#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

#define cls(x, y) memset(x, y, sizeof(x))
#define fly(...) fprintf(stderr, __VA_ARGS__)

inline int read()
{
	int x = 0, f = 1, c;
	while(c = getchar(), c < '0' || c > '9') if(c == '-') f = -1;
	for(; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
	return x * f;
}

inline char mygetchar()
{
	static char ch;
	while(ch = getchar(), ch < 'A' || ch > 'Z');
	return ch;
}

const int maxn = 100005;
const int maxm = 200005;
const int maxlog = 19;

int n, m, G, S, cnt, dfs_clock;
int head[maxn], size[maxn];
int next[maxm], v[maxm];
int fa[maxn], f[maxn];
int depth[maxn], pos[maxn];
int rmq[maxlog][maxm], LOG[maxm];
bool done[maxn]; int light[maxn];

struct Heap
{
	multiset<int> data;

	int size() { return data.size(); }
	int top() { return *data.rbegin(); }
	int get() { return top() + *++data.rbegin(); }
	void ins(int x) { data.insert(x); }
	void del(int x) { data.erase(data.find(x)); }

} A[maxn], B[maxn], C;
// A - 记录子树中所有节点到父亲节点的距离
// B - 记录所有子节点的堆顶
// C - 记录所有B中最大值和次大值之和

void addedge(int a, int b)
{
	v[m] = b, next[m] = head[a], head[a] = m++;
	v[m] = a, next[m] = head[b], head[b] = m++;
}

void input()
{
	n = read(); cls(head, -1);
	for(int i = 1; i < n; ++i)
		addedge(read(), read());
}

void root(int x, int p)
{
	size[x] = 1; f[x] = 0;
	for(int i = head[x]; ~i; i = next[i]) if(v[i] != p && !done[v[i]])
		{ root(v[i], x); size[x] += size[v[i]]; f[x] = max(f[x], size[v[i]]); }
	f[x] = max(f[x], S - size[x]); if(G == -1 || f[x] < f[G]) G = x;
}

void divide(int x, int p)
{
	fa[x] = p; done[x] = 1;
	for(int i = head[x]; ~i; i = next[i]) if(!done[v[i]])
		{ G = -1; S = size[v[i]]; root(v[i], x); divide(G, x); }
}

void dfs(int x, int p)
{
	rmq[0][pos[x] = ++dfs_clock] = depth[x] = depth[p] + 1;
	for(int i = head[x]; ~i; i = next[i]) if(v[i] != p)
		{ dfs(v[i], x); rmq[0][++dfs_clock] = depth[x]; }
}

void init_rmq()
{
	for(int i = 2; i <= dfs_clock; ++i) LOG[i] = LOG[i>>1] + 1;
	for(int i = 0; i < LOG[dfs_clock]; ++i)
		for(int j = 1; j+(1<<i+1)-1 <= dfs_clock; ++j)
			rmq[i+1][j] = min(rmq[i][j], rmq[i][j+(1<<i)]);
}

inline int lca(int x, int y)
{
	x = pos[x]; y = pos[y]; if(x > y) swap(x, y);
	int L = LOG[y-x+1]; return min(rmq[L][x], rmq[L][y-(1<<L)+1]);
}

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

#define remove(x) if(x.size() >= 2) C.del(x.get())
#define insert(x) if(x.size() >= 2) C.ins(x.get())
#define work(x, v) flag == 1 ? x.del(v) : x.ins(v)

void modify(int x, int flag)
{
	remove(B[x]); work(B[x], 0); insert(B[x]);
	for(int i = x; i; i = fa[i])
	{
		remove(B[fa[i]]);
		if(A[i].size()) B[fa[i]].del(A[i].top());
		work(A[i], dist(x, fa[i]));
		if(A[i].size()) B[fa[i]].ins(A[i].top());
		insert(B[fa[i]]);
	}
}

void build()
{
	G = -1; S = n; root(1, 0); divide(G, 0);
	dfs(1, 0); init_rmq(); cls(light, -1), cnt = n;
	for(int i = 1; i <= n; ++i) modify(i, -1);
}

inline void change(int x) { cnt += light[x]; modify(x, light[x] = -light[x]); }

void solve()
{
	register int Q = read();
	while(Q--)
	{
		if(mygetchar() == 'G')
		{
			if(!cnt) puts("-1");
			else if(cnt == 1) puts("0");
			else printf("%d\n", C.top());
		}
		else change(read());
	}
}

int main()
{
	freopen("hide.in", "r", stdin);
	freopen("hide.out", "w", stdout);
	
	input();
	build();
	solve();
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}