제출 #1287030

#제출 시각아이디문제언어결과실행 시간메모리
1287030marvinthang스핑크스 (IOI24_sphinx)C++20
100 / 100
337 ms1616 KiB
/*************************************
*    author: marvinthang             *
*    created: 06.09.2024 18:06:34    *
*************************************/

#include "sphinx.h"
#include <bits/stdc++.h>

using namespace std;

#define             fi  first
#define             se  second
#define           left  ___left___
#define          right  ___right___
#define   scan_op(...)  istream & operator >> (istream &in, __VA_ARGS__ &u)
#define  print_op(...)  ostream & operator << (ostream &out, const __VA_ARGS__ &u)
#define     file(name)  if (fopen(name".inp", "r")) { freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); }
#ifdef LOCAL
	#include "debug.h"
#else
	#define DB(...)
	#define db(...) ""
	#define debug(...)
#endif

namespace std {
template <class U, class V> scan_op(pair <U, V>) { return in >> u.first >> u.second; }
template <class T> scan_op(vector <T>) { for (size_t i = 0; i < u.size(); ++i) in >> u[i]; return in; }
template <class U, class V> print_op(pair <U, V>) { return out << '(' << u.first << ", " << u.second << ')'; }
template <size_t i, class T> ostream &print_tuple_utils(ostream &out, const T &tup) { if constexpr(i == tuple_size<T>::value) return out << ")"; else return print_tuple_utils<i + 1, T>(out << (i ? ", " : "(") << get<i>(tup), tup); }
template <class...U> print_op(tuple <U...>) { return print_tuple_utils<0, tuple <U...>>(out, u); }
template <class Con, class = decltype(begin(declval<Con>()))>typename enable_if <!is_same<Con, string>::value, ostream &>::type operator << (ostream &out, const Con &con) { out << '{'; for (__typeof(con.begin()) it = con.begin(); it != con.end(); ++it) out << (it == con.begin() ? "" : ", ") << *it; return out << '}'; }
template <class T> print_op(stack <T>) { vector <T> v; stack <T> st = u; while (!st.empty()) v.push_back(st.top()), st.pop(); reverse(v.begin(), v.end()); return out << v; }
template <class T> print_op(queue <T>) { queue <T> q = u; out << '{'; while (!q.empty()) { out << q.front(); q.pop(); if (!q.empty()) out << ", "; } out << '}'; return out; }
template <class T, class X, class Y> print_op(priority_queue <T, X, Y>) { priority_queue <T, X, Y> pq = u; out << '{'; while (!pq.empty()) { out << pq.top(); pq.pop(); if (!pq.empty()) out << ", "; } out << '}'; return out; }
template <class Fun> class y_combinator_result { Fun fun_; public: template <class T> explicit y_combinator_result(T &&fun): fun_(forward<T>(fun)) {} template <class...Args> decltype(auto)operator()(Args &&...args) { return fun_(ref(*this), forward<Args>(args)...); } };
template <class Fun> decltype(auto)y_combinator(Fun &&fun) { return y_combinator_result<decay_t<Fun>>(forward<Fun>(fun)); }
template <typename T, int D> struct Vec: public vector <Vec<T, D - 1>> { static_assert(D >= 1, "Vector dimension must be greater than zero!"); template <typename ...Args> Vec(int n = 0, Args ...args): vector <Vec<T, D - 1>>(n, Vec<T, D - 1>(args...)) {} };
template <typename T> struct Vec<T, 1>: public vector<T>{ Vec(int n = 0, const T &val = T()): vector<T>(n, val) {} };
#if __cplusplus < 202002L
	template <class T> int ssize(const T &a) { return a.size(); }
#endif
}

vector <int> find_colours(int n, vector <int> X, vector <int> Y) {
	int m = X.size();

	Vec <int, 2> adj(n);
	for (int i = 0; i < m; ++i) {
		adj[X[i]].push_back(Y[i]);
		adj[Y[i]].push_back(X[i]);
	}

	auto get_ncompx = [&] (const vector <int> &E, int x) {
		queue <int> q;
		int cnt = 0;
		vector <bool> visited(n);
		for (int i = 0; i < n; ++i) if (!visited[i] && E[i] == x) {
			++cnt;
			visited[i] = true;
			q.push(i);
			while (!q.empty()) {
				int u = q.front(); q.pop();
				for (int v: adj[u]) if (!visited[v] && E[v] == x) {
					visited[v] = true;
					q.push(v);
				}
			}
		}
		return cnt;
	};

	auto ask_ncomp = [&] (vector <int> E) {
		return perform_experiment(E) - get_ncompx(E, n);
	};

	vector <int> comp(n, -1);
	int ncomp = 0;
	vector <int> E(n, n);
	for (int u = 0; u < n; ++u) {
		E[u] = -1;
		int new_ncomp = ask_ncomp(E);
		if (ncomp < new_ncomp) {
			comp[u] = ncomp;
		} else {
			Vec <int, 2> lst(ncomp);
			int first = -1;
			for (int i = 0; i < u; ++i) lst[comp[i]].push_back(i);
			for (int t = 0, lt = 0; t <= ncomp - new_ncomp; ++t) {
				auto check = [&] (int i) {
					vector <int> E(n, n);
					E[u] = -1;
					for (int j = lt; j <= i; ++j) for (auto u: lst[j]) E[u] = -1;
					int actual = ask_ncomp(E);
					int expected = i - lt + 2;
					return actual < expected;
				};
				int l = lt, r = ncomp - 2;
				while (l <= r) {
					int m = (l + r) >> 1;
					if (check(m)) r = m - 1;
					else l = m + 1;
				}
				if (first == -1) {
					comp[u] = first = l;
				} else {
					for (int i = 0; i < n; ++i) if (comp[i] > comp[lst[l][0]]) --comp[i];
					for (int u: lst[l]) comp[u] = first;
				}
				lt = l + 1;
			}
		}
		ncomp = new_ncomp;
	}

	Vec <int, 2> cadj(ncomp);
	for (int i = 0; i < m; ++i) {
		X[i] = comp[X[i]];
		Y[i] = comp[Y[i]];
		cadj[X[i]].push_back(Y[i]);
		cadj[Y[i]].push_back(X[i]);
	}

	vector <int> f(ncomp, -1);

	queue <int> q;
	q.push(0);
	f[0] = 0;
	while (!q.empty()) {
		int u = q.front(); q.pop();
		for (int v: cadj[u]) if (f[v] == -1) {
			f[v] = !f[u];
			q.push(v);
		}
	}

	Vec <int, 2> list_f(2), list_comp(ncomp);
	for (int i = 0; i < n; ++i) list_comp[comp[i]].push_back(i);
	for (int i = 0; i < ncomp; ++i) list_f[f[i]].push_back(i);

	vector <int> comp_color(ncomp, -1);
	if (ncomp == 1) {
		for (int c = 0; c < n; ++c) {
			vector <int> E(n, c);
			E[0] = -1;
			if (ask_ncomp(E) == 1) {
				comp_color[0] = c;
				break;
			}
		}
	} else {
		for (int t = 0; t < 2; ++t) {
			for (int c = 0; c < n && !list_f[t].empty(); ++c) {
				int rt = ssize(list_f[t]);
				auto check = [&] (int i) {
					vector <int> E(n, c);
					for (int j = i + 1; j < rt; ++j) {
						for (int u: list_comp[list_f[t][j]]) E[u] = -1;
					}
					int actual = ask_ncomp(E);
					int expected = rt - i - 1 + get_ncompx(E, c);
					return actual == expected;
				};
				while (!check(-1)) {
					int l = 0, r = rt - 2;
					while (l <= r) {
						int m = (l + r) >> 1;
						if (check(m)) r = m - 1;
						else l = m + 1;
					}
					comp_color[list_f[t][l]] = c;
					list_f[t].erase(list_f[t].begin() + l);
					rt = l;
				}
			}
		}
	}

	vector <int> res(n);
	for (int i = 0; i < n; ++i) res[i] = comp_color[comp[i]];
	return res;
}
#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...