Submission #1300442

#TimeUsernameProblemLanguageResultExecution timeMemory
1300442rxlfd314Sphinx's Riddle (IOI24_sphinx)C++20
50 / 100
312 ms1804 KiB
#include "sphinx.h" #include <bits/stdc++.h> using namespace std; using ll = long long; using ari2 = array<int, 2>; using ari3 = array<int, 3>; using arl2 = array<ll, 2>; using arl3 = array<ll, 3>; template <class T> using vt = vector<T>; #define all(x) begin(x), end(x) #define size(x) (int((x).size())) #define REP(a,b,c,d) for(int a=(b);(d)>0?a<=(c):a>=(c);a+=(d)) #define FOR(a,b,c) REP(a,b,c,1) #define ROF(a,b,c) REP(a,b,c,-1) struct DSU { vt<int> uf; DSU(const int n) : uf(n, -1) {} int find(const int i) { return uf[i] < 0 ? i : uf[i] = find(uf[i]); } bool unite(int a, int b) { if ((a = find(a)) == (b = find(b))) return false; if (uf[a] > uf[b]) swap(a, b); uf[a] += uf[b]; uf[b] = a; return true; } }; int query(const vt<int> &E) { return perform_experiment(E); } vt<int> find_colours(const int N, const vt<int> X, const vt<int> Y) { const int M = size(X); vt<vt<int>> adj(N); FOR(i, 0, M - 1) { adj[X[i]].push_back(Y[i]); adj[Y[i]].push_back(X[i]); } DSU uf(N); const auto expect = [&](vt<int> E) { int cur = N + 1; FOR(i, 0, N - 1) if (E[i] < 0 && uf.find(i) == i) E[i] = cur++; FOR(i, 0, N - 1) E[i] = E[uf.find(i)]; DSU uf2(N); int ret = N; FOR(i, 0, M - 1) ret -= E[X[i]] == E[Y[i]] && uf2.unite(X[i], Y[i]); return ret; }; int timer = 0; vt<int> tin(N, -1), tout(N), rev_tin(N); const auto dfs = [&](auto &&self, const int i) -> void { rev_tin[tin[i] = timer++] = i; vt<int> s_roots; for (const auto &j : adj[i]) if (tin[j] < 0) s_roots.push_back(j), self(self, j); tout[i] = timer - 1; vt<int> links; for (const auto &j : s_roots) { vt<int> comps; FOR(k, tin[j], tout[j]) comps.push_back(uf.find(rev_tin[k])); sort(all(comps)); comps.erase(unique(all(comps)), comps.end()); int prv = -1; while (prv + 1 < size(comps)) { vt<int> E(N, N); E[i] = -1; FOR(k, prv + 1, size(comps) - 1) E[comps[k]] = -1; FOR(k, 0, N - 1) E[k] = E[uf.find(k)]; if (query(E) == expect(E)) break; int lo = prv + 1, hi = size(comps) - 1; while (lo < hi) { const int mid = lo + hi >> 1; FOR(k, prv + 1, mid) E[comps[k]] = -1; FOR(k, mid + 1, size(comps) - 1) E[comps[k]] = N; FOR(k, 0, N - 1) E[k] = E[uf.find(k)]; if (query(E) == expect(E)) lo = mid + 1; else hi = mid; } links.push_back(comps[lo]); prv = lo; } } for (const auto &j : links) uf.unite(i, j); }; dfs(dfs, 0); adj.assign(N, vt<int>()); FOR(i, 0, M - 1) { adj[uf.find(X[i])].push_back(uf.find(Y[i])); adj[uf.find(Y[i])].push_back(uf.find(X[i])); } vt<int> A, B, seen(N); const auto colour = [&](auto &&self, const int i, const int c) -> void { (c ? A : B).push_back(i); seen[i] = 1; for (const auto &j : adj[i]) if (!seen[j]) self(self, j, !c); }; colour(colour, uf.find(0), 0); vt<int> ans(N); FOR(_, 0, 1) { FOR(c, 0, N - 1) { vt<int> E(N); for (const auto &i : B) E[i] = c; int prv = -1; while (prv + 1 < size(A)) { FOR(i, 0, prv) E[A[i]] = N; FOR(i, prv + 1, size(A) - 1) E[A[i]] = -1; FOR(i, 0, N - 1) E[i] = E[uf.find(i)]; if (query(E) == expect(E)) break; int lo = prv + 1, hi = size(A) - 1; while (lo < hi) { const int mid = lo + hi >> 1; FOR(i, prv + 1, mid) E[A[i]] = -1; FOR(i, mid + 1, size(A) - 1) E[A[i]] = N; FOR(i, 0, N - 1) E[i] = E[uf.find(i)]; if (query(E) == expect(E)) lo = mid + 1; else hi = mid; } ans[A[lo]] = c; prv = lo; } } swap(A, B); } FOR(i, 0, N - 1) ans[i] = ans[uf.find(i)]; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...