记录编号 230414 评测结果 AAAAAAAAAA
题目名称 [SPOJ 2666] QTREE4 最终得分 100
用户昵称 Gravatardashgua 是否通过 通过
代码语言 C++ 运行时间 1.778 s
提交时间 2016-02-21 19:24:23 内存使用 18.34 MiB
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>

template<class Num>void read(Num &x)
{
	int flag = 1;
	char c;
	while((c = getchar()) < '0' || c > '9')
		if(c == '-') flag *= -1;
	x = c - '0';
	while((c = getchar()) >= '0' && c <= '9')
		x *= 10, x += c - '0';	
	x *= flag;	
}
template<class Num>void write(Num x)
{
	if(x == 0) {putchar('0');return;}
	if(x < 0) putchar('-'), x = -x;

	static int stack[20];
	int sl = 0;
	
	while(x) stack[sl++] = x % 10, x /= 10;
	while(sl) putchar(stack[--sl] + '0');
}
#define X first
#define Y second
#define L(x) ((x) << 1)
#define R(x) ((x) << 1 | 1)
const int maxn = 1e5 + 20, logN = 18, inf = 0x3f3f3f3f;
const int space = maxn << 2;

int *new_memory(int size)
{
	static int array[space], *ind = array;
	ind += size;
	return ind - size;
}
std::pair<int,int> *new_memory_pair(int size)
{
	static std::pair<int,int> array[space], *ind = array;
	ind += size;
	return ind - size;
}
struct Heap
{
	int *pos, size, maxs;
	std::pair<int,int> *heap;
	void setup(int spsize)
	{
		maxs = spsize, pos = new_memory(maxs + 1);
		heap = new_memory_pair(maxs + 1);
	}
	void update(int ind)
	{
		pos[heap[ind].Y] = ind;
	}
	void exchange(int a,int b)
	{
		std::swap(heap[a], heap[b]);
		update(a), update(b);
	}
	void pushdown(int x)
	{
		int maxid = x;
		
		if(L(x) <= size && heap[L(x)] > heap[maxid]) maxid = L(x);
		if(R(x) <= size && heap[R(x)] > heap[maxid]) maxid = R(x);
		if(maxid != x)
		{
			exchange(x, maxid);
			pushdown(maxid);
		}
	}
	void pushup(int x)
	{
		if(x == 1) return;
		
		int fa = x >> 1;
		
		if(heap[x] > heap[fa])
		{
			exchange(x, fa);
			pushup(fa);
		}
	}
	int top()
	{
		return size ? heap[1].X : -inf;
	}
	int tops()
	{
		if(size > 1)
		{
			if(size >= 3 && heap[3] > heap[2]) return heap[3].X;
			return heap[2].X;
		}
		return -inf;
	}
	void pop()
	{
		if(size == 0) return;
		pos[heap[1].Y] = 0;
		std::swap(heap[1], heap[size--]);
		if(size)
		{
			update(1);
			pushdown(1);
		}
	}
	void push(std::pair<int,int> t)
	{
		heap[++size] = t;
		update(size);
		pushup(size);
	}
	void change(int x,int y)
	{
		int t = pos[x];
		heap[t].X = y;
		pushdown(t);
		pushup(t);
	}
};
typedef std::pair<std::pair<int,int>,int> Seg;

int N, Q, white;
struct Edge
{
	int v, w, next;
}edge[maxn << 1];
int head[maxn], el;
int top[maxn], son[maxn], size[maxn], dep[maxn], fa[maxn], dist[maxn];
int dfn[maxn], ind[maxn], dl, top_dep[maxn];
int top_ind[maxn], top_cnt[maxn], fw[maxn];
Heap node[maxn], ans;
Seg seg[maxn << 2];
bool flag[maxn];

void newedge(int u,int v,int w)
{
	edge[++el] = (Edge){v, w, head[u]}, head[u] = el;
}
void init()
{
	int a, b, c;
	
	read(N);
	for(int i = 1; i < N; i++)
	{
		read(a), read(b), read(c);
		newedge(a, b, c);
		newedge(b, a, c);
	}
	read(Q);
	
	for(int i = 1; i <= N; i++) flag[i] = true;
	white = N;
}
void dfs(int a)
{
	size[a] = 1, dep[a] = dep[fa[a]] + 1;
		
	for(int i = head[a]; i ; i = edge[i].next)
	{
		int p = edge[i].v;
		if(p != fa[a])
		{
			dist[p] = dist[a] + edge[i].w;
			fa[p] = a, fw[p] = edge[i].w, dfs(p);
			if(size[p] > size[son[a]]) son[a] = p;
			size[a] += size[p];
		}
	}
}
void build(int a)
{
	dfn[++dl] = a, ind[a] = dl;
	
	if(son[fa[a]] == a)
	{
		top[a] = top[fa[a]];
		top_dep[top[a]] = a;
	}
	else
	{
		top[a] = a, top_dep[a] = a;
		top_ind[a] = ++top_cnt[fa[a]];
	}
	
	if(son[a]) build(son[a]);
	
	for(int i = head[a]; i ; i = edge[i].next)
	{
		int p = edge[i].v;
		if(p != fa[a] && p != son[a]) build(p);
	}
}
void update(int p,int l,int r)
{
	int mid = (l + r) >> 1;
	
	seg[p].X.X = std::max(seg[p << 1].X.X, seg[p << 1 | 1].X.X + dist[dfn[mid + 1]] - dist[dfn[l]]);
	seg[p].X.Y = std::max(seg[p << 1 | 1].X.Y, seg[p << 1].X.Y + dist[dfn[r]] - dist[dfn[mid]]);
	seg[p].Y = std::max(seg[p << 1].Y, seg[p << 1 | 1].Y);
	seg[p].Y = std::max(seg[p << 1].X.Y + seg[p << 1 | 1].X.X + dist[dfn[mid + 1]] - dist[dfn[mid]], seg[p].Y);
}
Seg gather(Seg a,Seg b,int l,int d,int r)
{
	Seg ret;
	ret.X.X = std::max(a.X.X, b.X.X + dist[dfn[d + 1]] - dist[dfn[l]]);
	ret.X.Y = std::max(b.X.Y, a.X.Y + dist[dfn[r]] - dist[dfn[d]]);
	ret.Y = std::max(a.X.Y + b.X.X + dist[dfn[d + 1]] - dist[dfn[d]], std::max(a.Y, b.Y));
	return ret;
}
void seg_build(int l,int r,int ll,int rr,int p)
{
	if(ll == rr)
	{
		int maxL = std::max(node[dfn[l]].top(), flag[dfn[l]] ? 0 : -inf);
		int maxR = std::max(node[dfn[l]].top(), flag[dfn[r]] ? 0 : -inf);
		int opt = std::max(flag[dfn[l]] ? std::max(0, node[dfn[l]].top()) : -inf, node[dfn[l]].top() + node[dfn[l]].tops());
		seg[p] = std::make_pair(std::make_pair(maxL, maxR), opt);
	}
	else
	{
		int mid = (ll + rr) >> 1;
		if(r <= mid) seg_build(l, r, ll, mid, p << 1);
		else if(l > mid) seg_build(l, r, mid + 1, rr, p << 1 | 1);
		else
		{
			seg_build(l, mid, ll, mid, p << 1);
			seg_build(mid + 1, r, mid + 1, rr, p << 1 | 1);
		}
		update(p, ll, rr);
	}
}
void seg_update(int k,int l,int r,int p)
{
	if(l == r)
	{
		int maxL = std::max(node[dfn[l]].top(), flag[dfn[l]] ? 0 : -inf);
		int maxR = std::max(node[dfn[l]].top(), flag[dfn[r]] ? 0 : -inf);
		int opt = std::max(flag[dfn[l]] ? std::max(0, node[dfn[l]].top()) : -inf, node[dfn[l]].top() + node[dfn[l]].tops());
		seg[p] = std::make_pair(std::make_pair(maxL, maxR), opt);
	}
	else
	{
		int mid = (l + r) >> 1;
		if(k <= mid) seg_update(k, l, mid, p << 1);
		else seg_update(k, mid + 1, r, p << 1 | 1);
		update(p, l, r);
	}
}
Seg seg_query(int l,int r,int ll,int rr,int p)
{
	if(l == ll && r == rr) return seg[p];
	else
	{
		int mid = (ll + rr) >> 1;
		if(r <= mid) return seg_query(l, r, ll, mid, p << 1);
		else if(l > mid) return seg_query(l, r, mid + 1, rr, p << 1 | 1);
		else return gather(seg_query(l, mid, ll, mid, p << 1), seg_query(mid + 1, r, mid + 1, rr, p << 1 | 1), l, mid, r);
	}
}
void prework()
{	
	ans.setup(N);
	for(int i = 1; i <= N; i++)
		if(top_cnt[i]) node[i].setup(top_cnt[i]);
	
	for(int i = N, j = N, t; i >= 1; i = j)
	{
		while(j > 0 && top[dfn[j]] == top[dfn[i]]) j--;
		seg_build(j + 1, i, 1, N, 1), t = dfn[j + 1];
		Seg w = seg_query(j + 1, i, 1, N, 1);
		if(fa[t]) node[fa[t]].push(std::make_pair(w.X.X + fw[t], top_ind[t]));
		ans.push(std::make_pair(w.Y, top[t]));
	}
}
void solve()
{
	char ch[3]; int x;
	static int acnt = 0;
	
	scanf("%s", ch);
	if(ch[0] == 'C')
	{
		read(x);
		
		if(flag[x])
			white--, flag[x] = false;
		else
			white++, flag[x] = true;
			
		for(int t = x; t; t = fa[top[t]])
		{
			seg_update(ind[t], 1, N, 1);
			Seg k = seg_query(ind[top[t]], ind[top_dep[top[t]]], 1, N, 1);
			if(fa[top[t]]) node[fa[top[t]]].change(top_ind[top[t]], k.X.X + fw[top[t]]);
			ans.change(top[t], k.Y);
		}
/*		
		for(int i = 1; i <= ans.size; i++)
			std::cerr << ans.heap[i].X << std::endl;
*/
	}
	else
	{
		if(!white) puts("They have disappeared.");
		else write(std::max(ans.top(), 0)), puts("");
	}
}
int main()
{
	freopen("QTREE4.in","r",stdin);
	freopen("QTREE4.out","w",stdout);

	init();

	dfs(1), build(1);
	
	prework();
	
	while(Q--) solve();

	fclose(stdin);
	fclose(stdout);
	return 0;		
}