QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#18331#2214. Link Cut DigraphKomeijiRE 0ms0kbC++202.6kb2022-01-17 21:12:052022-05-04 17:58:23

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-05-04 17:58:23]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2022-01-17 21:12:05]
  • 提交

answer

#include <bits/stdc++.h>

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	int n, m;
	std::cin >> n >> m;
	std::vector<std::pair<int, int>> edges;
	std::vector<int> f(n + 1), vis(n + 1), ans(n + 1), dfn(n + 1), low(n + 1), scc(n + 1), ins(n + 1), siz(n + 1, 1);
	std::iota(f.begin(), f.end(), 0);
	std::stack<int> stack;
	int curt = 0, dfnt = 0, stot = 0;
	for (int i = 0; i < m; ++i) {
		int x, y;
		std::cin >> x >> y;
		edges.emplace_back(x, y);
	}
	auto find = [&](int x) {
		while (x != f[x])
			x = f[x] = f[f[x]];
		return x;
	};
	std::vector<std::vector<int>> G(n + 1, std::vector<int>());
	std::function<void(int)> tarjan = [&](int x) {
		low[x] = dfn[x] = ++dfnt;
		stack.emplace(x);
		ins[x] = true;
		for (int y : G[x]) {
			if (!dfn[y]) {
				tarjan(y);
				low[x] = std::min(low[x], low[y]);
			}
			else if (ins[y]) {
				low[x] = std::min(low[x], dfn[y]);
			}
		}
		if (dfn[x] == low[x]) {
			++stot;
			int y;
			do {
				y = stack.top(); stack.pop();
				ins[y] = false;
				scc[y] = stot;
			} while (y != x);
		}
	};
	std::function<void(int, int, std::vector<int>)> solve = [&](int l, int r, std::vector<int> eids) {
		const int mid = l + r >> 1;
		++curt;
		std::vector<int> nodes;
		auto push = [&](int x) {
			if (vis[x] != curt) {
				vis[x] = curt;
				nodes.push_back(x);
			}
		};
		for (int o : eids) {
			if (o <= mid) {
				auto [x, y] = edges[o];
				x = find(x), y = find(y);
				push(x), push(y);
				if (x != y) {
					G[x].push_back(y);
				}
			}
		}
		for (int x : nodes)
			assert(!dfn[x]);
		for (int x : nodes)
			if (!dfn[x])
				tarjan(x);
		if (l == r) {
			if (l) ans[l] = ans[l - 1];
			for (int o: eids) {
				auto [x, y] = edges[o];
				if (find(x) != find(y) && scc[find(x)] == scc[find(y)]) {
					int _x = x, _y = y;
					x = find(x);
					y = find(y);
					ans[l] += 1ll * siz[x] * siz[y];
					siz[y] += siz[x], siz[x] = 0;
					f[x] = y;
				}
			}
			for (int x : nodes) G[x].clear(), dfn[x] = low[x] = ins[x] = scc[x] = 0;
			dfnt = stot = 0;
			while (!stack.empty())
				stack.pop();
		}
		else {
			std::vector<int> le, ri;
			for (int o : eids) {
				auto [x, y] = edges[o];
				if (find(x) == find(y)) continue;
				if (o <= mid && scc[x] == scc[y]) {
					le.push_back(o);
				}
				else {
					ri.push_back(o);
				}
			}
			for (int x : nodes) G[x].clear(), dfn[x] = low[x] = ins[x] = scc[x] = 0;
			dfnt = stot = 0;
			while (!stack.empty())
				stack.pop();
			solve(l, mid, le);
			solve(mid + 1, r, ri);
		}
	};
	std::vector<int> eids(m);
	std::iota(eids.begin(), eids.end(), 0);
	solve(0, m - 1, eids);
	for (int i = 0; i < m; ++i)
		std::cout << ans[i] << '\n';
	return 0;
}

详细

Test #1:

score: 0
Runtime Error