제출 #435137

#제출 시각아이디문제언어결과실행 시간메모리
435137Elegia열쇠 (IOI21_keys)C++17
100 / 100
2171 ms135484 KiB
#include <bits/stdc++.h>

using namespace std;

void merge(set<int>& x, set<int>& y) {
	if (x.size() < y.size()) swap(x, y);
	for (int i : y) x.insert(i);
	y.clear();
}
void merge(map<int, list<int>>& x, map<int, list<int>>& y) {
	if (x.size() < y.size()) swap(x, y);
	for (auto it = y.begin(); it != y.end(); ++it) {
		list<int>& l = x[it->first];
		l.splice(l.begin(), it->second);
	}
	y.clear();
}

vector<int> find_reachable(vector<int> r, vector<int> u, vector<int> v, vector<int> c) {
	int n = r.size(), m = u.size();
	vector<int> ans(n), dsu(n), sz(n, 1), vis(n);
	vector<set<int>> key(n);
	vector<map<int, list<int>>> candidate(n);
	vector<list<int>> edge(n);
	iota(dsu.begin(), dsu.end(), 0);
	function<int(int)> find = [&](int x) { return dsu[x] == x ? x : dsu[x] = find(dsu[x]); };
	auto activate = [&](const set<int>& kk, map<int, list<int>>& cc, list<int>& ed) {
		if (kk.size() < cc.size()) {
			for (int i : kk) {
				auto it = cc.find(i);
				if (it != cc.end()) {
					ed.splice(ed.begin(), it->second);
					cc.erase(it);
				}
			}
		} else {
			for (auto it = cc.begin(); it != cc.end();) if (kk.count(it->first)) {
				ed.splice(ed.begin(), it->second);
				cc.erase(it++);
			} else ++it;
		}
	};
	auto mer = [&](int x, int y) {
		x = find(x); y = find(y);
		if (x == y) return;
		activate(key[x], candidate[y], edge[x]);
		activate(key[y], candidate[x], edge[x]);
		edge[x].splice(edge[x].begin(), edge[y]);
		merge(key[x], key[y]);
		merge(candidate[x], candidate[y]);
		sz[x] += sz[y];
		dsu[y] = x;
	};

	for (int i = 0; i != m; ++i) {
		candidate[u[i]][c[i]].push_back(v[i]);
		candidate[v[i]][c[i]].push_back(u[i]);
	}
	for (int i = 0; i != n; ++i) {
		key[i].insert(r[i]);
		activate(key[i], candidate[i], edge[i]);
	}
	stack<int> stk;
	function<void(int)> dfs = [&](int x) {
		stk.push(x);
		vis[x] = -2;
		while (!edge[x].empty()) {
			int y = find(edge[x].back()); edge[x].pop_back();
			if (y == x) continue;
			if (vis[y] > 0 || vis[y] == -1) {
				vis[x] = -1;
				stk.pop();
				return;
			}
			if (vis[y] == -2) {
				while (stk.top() != y) {
					stk.pop();
					mer(stk.top(), x);
				}
				return;
			}
			dfs(y);
			if (stk.top() != x) return;
			y = find(y);
			if (vis[y] > 0 || vis[y] == -1) {
				vis[x] = -1;
				stk.pop();
				return;
			}
		}
		vis[x] = sz[x];
		stk.pop();
		return;
	};
	for (int i = 0; i != n; ++i) if (dsu[i] == i && vis[i] == 0)
		dfs(i);
	int minv = n + 1;
	for (int i = 0; i != n; ++i) if (vis[i] > 0) minv = min(minv, vis[i]);
	for (int i = 0; i != n; ++i) ans[i] = vis[find(i)] == minv;

	return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...