Submission #380613

# Submission time Handle Problem Language Result Execution time Memory
380613 2021-03-22T12:56:49 Z KoD Simurgh (IOI17_simurgh) C++17
0 / 100
1 ms 364 KB
#include <bits/stdc++.h>
#include "simurgh.h"

template <class T>
using Vec = std::vector<T>;

template <class F>
struct RecLambda: private F {
	explicit RecLambda(F &&f): F(std::forward<F>(f)) { }
	template <class... Args>
	decltype(auto) operator () (Args&&... args) const {
		return F::operator()(*this, std::forward<Args>(args)...);
	}
};

struct DSU {
	Vec<int> par;
	DSU(const int n): par(n, -1) { }
	int find(const int u) {
		return par[u] < 0 ? u : par[u] = find(par[u]);
	}	
	bool merge(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y) return false;
		if (par[x] > par[y]) std::swap(x, y);
		par[x] += par[y];
		par[y] = x;
		return true;
	}
};

Vec<int> find_roads(int n, Vec<int> u, Vec<int> v) {
	const int m = (int) u.size();
	Vec<Vec<int>> graph(n);
	std::map<std::pair<int, int>, int> edge;
	for (int i = 0; i < m; ++i) {
		graph[u[i]].push_back(v[i]);
		graph[v[i]].push_back(u[i]);
		edge[{ u[i], v[i] }] = i;
		edge[{ v[i], u[i] }] = i;
	}
	std::set<int> tree;
	Vec<int> back;
	Vec<int> parent(n), depth(n, -1);
	RecLambda([&](auto dfs, const int u, const int p, const int d) -> void {
		parent[u] = p;
		depth[u] = d;
		for (const auto v: graph[u]) {
			if (v != p) {
				if (depth[v] == -1) {
					tree.insert(edge[{ u, v }]);
					dfs(v, u, d + 1);
				}
				else {
					if (depth[v] < depth[u]) {
						back.push_back(edge[{ u, v }]);
					}
				}
			}
		}
	})(0, -1, 0);
	const auto base = count_common_roads(Vec<int>(tree.begin(), tree.end()));
	const auto exchange = [&](const int e, const int f) {
		tree.erase(e);
		tree.insert(f);
		const auto ret = count_common_roads(Vec<int>(tree.begin(), tree.end()));
		tree.erase(f);
		tree.insert(e);
		return ret;
	};
	Vec<int> state(m);
	for (const auto e: back) {
		int a = u[e], b = v[e];
		if (depth[a] < depth[b]) {
			std::swap(a, b);
		}
		Vec<int> done, same, differ;
		while (a != b) {
			const auto p = parent[a];
			const auto f = edge[{ a, b }];
			if (state[f] == 0) {
				const auto tmp = exchange(e, f);
				if (exchange(e, f) == base) {
					same.push_back(f);
				}
				else {
					state[e] = (tmp > base ? 1 : -1);
					differ.push_back(f);
				}
			}
			else {
				done.push_back(f);
			}
			a = p;
		}
		if (state[e] == 0 && same.size() + differ.size() > 0) {
			if (done.empty()) {
				state[e] = -1;
			}
			else {
				const auto f = done.front();
				const auto tmp = exchange(e, f);
				if (tmp == base) {
					state[e] = state[f];
				}
				else {
					state[e] = -state[f];
				}
			}
		}
		for (const auto f: same) {
			state[f] = state[e];
		}
		for (const auto f: differ) {
			state[f] = -state[e];
		}
	}
	for (const auto e: tree) {
		if (state[e] == 0) {
			state[e] = 1;
		}
	}
	const auto count = [&](const Vec<int> &es) {
		Vec<int> ask;
		ask.reserve(n - 1);
		DSU dsu(n);
		for (const auto e: es) {
			ask.push_back(e);
			dsu.merge(u[e], v[e]);
		}
		int sum = 0;
		for (const auto e: tree) {
			if (dsu.merge(u[e], v[e])) {
				ask.push_back(e);
				sum += (state[e] == 1);
			}
		}
		return count_common_roads(ask) - sum;
	};
	for (int i = 0; i < n; ++i) {
		std::set<int> remain;
		for (const auto j: graph[i]) {
			const auto e = edge[{ i, j }];
			if (state[e] == 0) {
				remain.insert(e);
			}
		}
		while (true) {
			Vec<int> vec(remain.begin(), remain.end());
			if (count(vec) == 0) {
				break;
			}
			while (vec.size() > 1) {
				const auto m = (int) vec.size() / 2;
				Vec<int> left(vec.begin(), vec.begin() + m);
				Vec<int> right(vec.begin() + m, vec.end());
				if (count(left) > 0) {
					vec = std::move(left);
				}
				else {
					vec = std::move(right);
				}
			}
			state[vec[0]] = 1;
			remain.erase(vec[0]);
		}
		for (const auto e: remain) {
			state[e] = -1;
		}
	}
	Vec<int> ret;
	for (int i = 0; i < m; ++i) {
		if (state[i] == 1) {
			ret.push_back(i);
		}
	}
	return ret;
}
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 364 KB WA in grader: NO
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 364 KB WA in grader: NO
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 364 KB WA in grader: NO
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 364 KB correct
2 Incorrect 1 ms 364 KB WA in grader: NO
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 364 KB WA in grader: NO
2 Halted 0 ms 0 KB -