求助,从P2056过来的,56pts
查看原帖
求助,从P2056过来的,56pts
203821
Lambent_Light楼主2022/7/20 11:20

RT

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int MAXN = 100005, INF = 1e9 + 2077;
struct edge{
	int to, w, next;
}e[MAXN << 1];
struct heap{
	priority_queue<int> q1, q2;
	int size() {return q1.size() - q2.size();}
	void push(int x) {q1.push(x);}
	void erase(int x) {q2.push(x);}
	void pop() {
		if (!q2.empty() && !q1.empty())
			while (q1.top() == q2.top()) {
		    	q1.pop(), q2.pop();
		    	if (q2.empty() || q1.empty()) break;
			}
		q1.pop();
	}
	int top() {
		if (!q2.empty() && !q1.empty())
			while (q1.top() == q2.top()) {
		    	q1.pop(), q2.pop();
		    	if (q2.empty() || q1.empty()) break;
			}
		return !size() ? -INF : q1.top();
	}
	int sec()	{
		if (size() < 2) return -INF;
		int x = top();
		pop();
		int y = top();
		push(x);
		return y;
	}
	int get() {
    	if (size() >= 2) return top() + sec();
    	if (size() == 1) return top();
    	return -INF;
    }
}q, q1[MAXN], q2[MAXN];
int n, m, cnt, head[MAXN], fa[MAXN], g[MAXN][21], d[MAXN], dep[MAXN], sum;
int root, s, dp[MAXN], size[MAXN];
bool vis[MAXN], flag[MAXN];
void add(int u, int v, int w)
{
	e[++cnt].to = v;
	e[cnt].w = w;
	e[cnt].next = head[u];
	head[u] = cnt;
	return ;
}
void dfs(int u, int f)
{
	dep[u] = dep[f] + 1;
	g[u][0] = f;
	for (int i = 1; i <= 20; i++)
	    g[u][i] = g[g[u][i - 1]][i - 1];
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].to;
		if (v == f) continue;
		d[v] = d[u] + e[i].w;
		dfs(v, u);
	}
	return ;
}
int lca(int x, int y)
{
	if (dep[x] < dep[y]) swap(x, y);
	for (int i = 20; i >= 0; i--)
	    if (dep[g[x][i]] >= dep[y]) x = g[x][i];
	if (x == y) return x;
	for (int i = 20; i >= 0; i--)
	    if (g[x][i] != g[y][i]) {
	    	x = g[x][i];
	    	y = g[y][i];
		} 
	return g[x][0];
}
int getdis(int x, int y)
{
	return d[x] + d[y] - 2 * d[lca(x, y)];
}
void getroot(int u, int f)
{
	//printf("%d %d\n", u, f);
	dp[u] = 0;
	size[u] = 1;
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].to;
		//printf("%d\n", v);
		if (v == f || vis[v]) continue;
		getroot(v, u);
		size[u] += size[v];
		dp[u] = max(dp[u], size[v]);
	}
	dp[u] = max(dp[u], s - size[u]);
	if (dp[u] < dp[root]) root = u;
	return ;
}
void build(int u)
{
	vis[u] = true;
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].to;
		if (vis[v]) continue;
		s = size[v], root = 0;
		getroot(v, 0), getroot(root, 0);
		fa[root] = u;
		build(root);
	}
	return ;
}
void update(int u)
{
	if (flag[u]) {
		sum++;
		q2[u].push(0);
		if (q2[u].size() == 2) 
		    q.push(q2[u].top());
	}
	else {
		sum--;
		if (q2[u].size() == 2) 
		    q.erase(q2[u].top());
		q2[u].erase(0);
	}
	int now = u;
	while (fa[now]) {
		int dis = getdis(fa[now], u), t;
		if (flag[u]) t = q1[now].top(), q1[now].push(dis);
	    else q1[now].erase(dis), t = q1[now].top();
	    if (dis > t) {
	    	int s1 = q2[fa[now]].get(), siz = q2[fa[now]].size();
	    	if (flag[u]) {
	    		if (t != -INF) q2[fa[now]].erase(t);
	    		q2[fa[now]].push(dis);
			}
			else {
				q2[fa[now]].erase(dis);
				if (t != -INF) q2[fa[now]].push(t);
			}
			int s2 = q2[fa[now]].get();
			if (s1 != s2) {
				if (siz >= 2) q.erase(s1);
				if (q2[fa[now]].size() >= 2) q.push(s2);
			}
		}
		now = fa[now];
	}
	return ;
}
int main()
{
	scanf("%d", &n);
	for (int i = 1; i < n; i++) {
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		add(a, b, c);
		add(b, a, c);
	}
	dfs(1, 0);
	s = dp[0] = n;
	getroot(1, 0);
	getroot(root, 0);
	build(root);
	for (int i = 1; i <= n; i++)
		flag[i] = true;
	for (int i = 1; i <= n; i++)
		update(i);
	scanf("%d", &m);
	for (int i = 1; i <= m; i++) {
		char s[2];
		scanf("%s", &s);
		if (s[0] == 'A') {
			if (sum >= 2) printf("%d\n", max(q.top(), 0));
			else if (sum == 1) printf("0\n");
			else printf("They have disappeared.\n");
		}
		else {
			int x;
			scanf("%d", &x);
			flag[x] = !flag[x];
			update(x);
		}
	}
	return 0;
} 
2022/7/20 11:20
加载中...