576E

咕咕咕


容易想到用线段树分治。然而我不断 WA。这说明要写强力的 gen。

有个问题就是一个边不能加入的时候,要改掉它的颜色,在后来仍然加入。

#include <bits/stdc++.h>

const int MAXN = 500010;
int st[MAXN], ids[MAXN], top;
struct dsu {
	int idx;
	int fa[MAXN], sz[MAXN]; bool fae[MAXN];
	void init(int ix, int n) {
		idx = ix;
		for (int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1;
	}
	std::pair<int, int> find(int x) {
		int res = 0;
		while (x != fa[x]) res ^= fae[x], x = fa[x];
		return std::make_pair(x, res);
	}
	void pop() {
		int x = st[top], y = fa[x];
		sz[y] -= sz[x]; fa[x] = x; fae[x] = 0;
		--top;
	}
	bool link(int x, int y) {
		int ex, ey;
		std::tie(x, ex) = find(x);
		std::tie(y, ey) = find(y);
		if (x != y) {
			if (sz[x] > sz[y]) std::swap(x, y);
			st[++top] = x, ids[top] = idx;
			fae[x] = ex ^ ey ^ 1;
			sz[y] += sz[x];
			fa[x] = y;
			return true;
		}
		return (ex ^ ey) == 1;
	}
} ss[51];
int n, m, K, Q;
int xs[MAXN], ys[MAXN];
int col[MAXN], lst[MAXN], disa[MAXN];
const int MAXQ = MAXN * 50;
struct qry { int id, c; } fir[MAXN];
int qh[MAXN << 2], qn[MAXQ], qt[MAXQ], tot;
int pre[MAXN], faqry[MAXN], elst[MAXN];
int find(int x) { return x == faqry[x] ? x : faqry[x] = find(faqry[x]); }
void addq(int u, int l, int r, int L, int R, int v) {
	if (L <= l && r <= R) {
		qn[++tot] = qh[u]; qt[qh[u] = tot] = v;
		return ;
	}
	int mid = l + r >> 1;
	if (L <= mid) addq(u << 1, l, mid, L, R, v);
	if (mid < R) addq(u << 1 | 1, mid + 1, r, L, R, v);
}
void addq(int l, int r, int id) {
	fir[l] = (qry) {id, col[id]}; faqry[l] = l;
	pre[l] = elst[id]; elst[id] = l;
	if (l + 1 <= r) addq(1, 1, Q, l + 1, r, l);
}
void solve(int u, int l, int r) {
	int nowtop = top;
	for (int i = qh[u]; i; i = qn[i]) {
		const int v = find(qt[i]);
		if (v) {
			const qry t = fir[v];
			ss[t.c].link(xs[t.id], ys[t.id]);
		}
	}
	if (l == r) {
		static qry t; t = fir[l];
		disa[l] = !ss[t.c].link(xs[t.id], ys[t.id]);
		if (disa[l]) faqry[l] = pre[faqry[l]];
	} else {
		int mid = l + r >> 1;
		solve(u << 1, l, mid); solve(u << 1 | 1, mid + 1, r);
	}
	while (top > nowtop) ss[ids[top]].pop();
}
int main() {
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> n >> m >> K >> Q;
	for (int i = 1; i <= K; ++i) ss[i].init(i, n);
	for (int i = 1; i <= m; ++i)
		std::cin >> xs[i] >> ys[i];
	for (int i = 1, e, v; i <= Q; ++i) {
		std::cin >> e >> v;
		if (col[e]) addq(lst[e], i - 1, e);
		col[e] = v, lst[e] = i;
	}
	for (int i = 1; i <= m; ++i) if (col[i])
		addq(lst[i], Q, i);
	solve(1, 1, Q);
	const char out[][10] = {"YES", "NO"};
	for (int i = 1; i <= Q; ++i)
		std::cout << out[disa[i]] << '
';
	return 0;
}
原文地址:https://www.cnblogs.com/daklqw/p/12101344.html