线段树维护直径wa求调
查看原帖
线段树维护直径wa求调
563650
haochengw920楼主2024/4/1 23:00
#include<cstdio>
#include<vector>
#include<algorithm>
#define INF (0x3f3f3f3f)
using namespace std;

const int MAXN = 400005;

int n, Q;
struct edge {
	int to, nex;
}e[MAXN]; int idx, head[MAXN];
inline void add(int u, int v) {
	e[++ idx].to = v;
	e[idx].nex = head[u];
	head[u] = idx;
}

namespace Tree {
	int timer, eu[MAXN];
	int dep[MAXN], dfn[MAXN];
	int lg[MAXN], f[MAXN][25];
	inline void dfs(int u, int fath) {
		eu[dfn[u] = ++ timer] = u;
		if (u == 1) dep[u] = 1;
		for (int i = head[u]; i; i = e[i].nex) {
			int v = e[i].to;
			if (v == fath) continue;
			dep[v] = dep[u] + 1;
			dfs(v, u);
			eu[++ timer] = u;
		}
	}
	inline int _min(int u, int v) {
		return (dep[u] < dep[v]) ? u : v;
	}
	inline void Init() {
		dep[0] = INF;
		for (int i = 2; i <= timer; ++ i)
			lg[i] = lg[i >> 1] + 1;
		for (int i = 1; i <= timer; ++ i)
			f[i][0] = eu[i];
		for (int j = 1; j <= lg[timer]; ++ j)
			for (int i = 1; i <= timer; ++ i)
				f[i][j] = _min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
	}
	inline int dist(int u, int v) {
		int l = min(dfn[u], dfn[v]);
		int r = max(dfn[u], dfn[v]);
		int len = lg[r - l + 1];
		int lca = _min(f[l][len], f[r - (1 << len) + 1][len]);
		return dep[u] + dep[v] - 2 * dep[lca];
	}
	inline void premain() {
		scanf ("%d", &n);
		for (int i = 1; i < n; ++ i) {
			int u, v;
			scanf ("%d%d", &u, &v);
			add(u, v); add(v, u);
		}
		dfs(1, 0); Init();
	}
}

class Segment_tree {
	#define lc (u << 1)
	#define rc (u << 1 | 1)
	private : 
	int dst[MAXN << 2];
	int p[MAXN << 2][2];
	vector<int>nd;
	inline void push_up(int u) {
		p[u][0] = p[u][1] = 0;
		nd.clear();
		if (p[lc][0]) nd.push_back(p[lc][0]);
		if (p[lc][1]) nd.push_back(p[lc][1]);
		if (p[rc][0]) nd.push_back(p[rc][0]);
		if (p[rc][1]) nd.push_back(p[rc][1]);
		int len = nd.size(), mx = -1, dis;
		for (int i = 1; i < len; ++ i)
			for (int j = 0; j < i; ++ j) 
				if ((dis = Tree::dist(nd[i], nd[j])) > mx) 
					p[u][0] = nd[j], p[u][1] = nd[i], mx = dis;
		dst[u] = mx;
		if (!~mx) p[u][0] = nd[0];
	}
	public : 
	inline void Build(int u = 1, int l = 1, int r = n) {
		if (l == r) {
			dst[u] = 0;
			p[u][0] = l, p[u][1] = 0;
			return;
		}
		int mid = (l + r) >> 1;
		Build(lc, l, mid);
		Build(rc, mid + 1, r);
		push_up(u);
	}
	inline void Modify(int x, int u = 1, int l = 1, int r = n) {
		if (l == r) {
			if (!dst[u]) dst[u] = -1, p[u][0] = p[u][1] = 0;
			else dst[u] = 0, p[u][0] = l, p[u][1] = 0;
			return;  
		}
		int mid = (l + r) >> 1;
		if (x <= mid) Modify(x, lc, l, mid);
		else Modify(x, rc, mid + 1, r);
		push_up(u);
	}
	inline int Query() {
		return dst[1];
	}
	#undef lc
	#undef rc
}st;

int cnt, t[MAXN];
inline void Solve() {
	scanf ("%d", &Q);
	char op[10];
	int p;
	cnt = n;
	while (Q --) {
		scanf ("%s", op);
		if (op[0] == 'G')
			printf ("%d\n", (cnt ^ 1) ? st.Query() : 0);
		else {
			scanf ("%d", &p);
			cnt += t[p]; cnt -= (t[p] ^= 1);
			st.Modify(p);
		}
	}
}

int main()
{
	Tree::premain();
	st.Build();
	Solve();
	return 0;
}
2024/4/1 23:00
加载中...