#include <bits/stdc++.h>
#include "sphinx.h"
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
#define all(v) v.begin(), v.end()
ll _ = 0;
int count_components(ll N, vector<vector<ll>> &adj, const std::vector<int>& colors) {
	int components_cnt = 0;
	std::vector<bool> vis(N, false);
	for (int i = 0; i < N; i++) {
		if (vis[i])
			continue;
		components_cnt++;
		std::queue<int> q;
		vis[i] = true;
		q.push(i);
		while (!q.empty()) {
			int cur = q.front();
			q.pop();
			for (int nxt : adj[cur])
				if (!vis[nxt] && colors[nxt] == colors[cur]) {
					vis[nxt] = true;
					q.push(nxt);
				}
		}
	}
	return components_cnt;
}
ll expected(ll n, vector<vector<ll>> &adj, vector<ll> &nodes, ll l, ll r, set<ll> &exc) {
	vector<int> query(n, n);
	for (ll i = l; i <= r; i++) if (!exc.count(nodes[i])) query[nodes[i]] = 0;
	return count_components(n, adj, query);
}
map<vector<int>, int> mem;
int perform_experiment_cached(vector<int> col) {
    if (mem.count(col)) return mem[col];
    return mem[col] = perform_experiment(col);
}
ll ask(ll n, vector<vector<ll>> &adj, vector<ll> &nodes, ll l, ll r, ll col) {
	vector<int> query(n, col);
	for (ll i = l; i <= r; i++) query[nodes[i]] = -1;
	return perform_experiment_cached(query);
}
ll ask(ll n, vector<vector<ll>> &adj, vector<ll> &nodes, ll l, ll r, ll col, vector<ll> ids) {
	vector<int> query(n, col);
	for (ll i = l; i <= r; i++) if (find(all(ids), i) == ids.end()) query[nodes[i]] = -1;
	return perform_experiment_cached(query);
}
void solve_red(ll n, vector<vector<ll>> &adj, vector<int> &res, vector<ll> &red) {
	vector<ll> nodes;
	for (ll i = 0; i < n; i++) if (red[i]) nodes.push_back(i);
	for (ll col = 0; col < n; col++) {
		set<ll> exc;
		ll _start = expected(n, adj, nodes, 0, nodes.size()-1, exc);
		ll start = ask(n, adj, nodes, 0, nodes.size()-1, col);
		while (start != _start) {
			ll l = 0, r = nodes.size()-1;
			while (l < r) {
				ll mid = l + (r - l) / 2;
				ll _q = expected(n, adj, nodes, l, mid, exc);
				ll q = ask(n, adj, nodes, l, mid, col);
				if (q != _q) r = mid;
				else l = mid + 1;
			}
			res[nodes[l]] = col;
			exc.insert(nodes[l]);
			_start = expected(n, adj, nodes, 0, nodes.size()-1, exc);
		}
	}
}
void solve_blue(ll n, vector<vector<ll>> &adj, vector<int> &res, vector<ll> &red) {
	vector<ll> nodes;
	for (ll i = 0; i < n; i++) if (!red[i]) nodes.push_back(i);
	for (ll col = 0; col < n; col++) {
		vector<ll> ids;
        auto recent = [&](ll l, ll r) -> optional<ll> {
            optional<ll> res = nullopt;
            for (auto &e : ids) if (e >= l && e <= r) res = e;
            return res;
        };
        auto without = [&](ll e) -> vector<ll> {
            vector<ll> res = ids;
            res.erase(find(all(res), e));
            return res;
        };
        auto count_rem = [&](ll l, ll r) -> ll {
            ll res = r - l + 1;
            for (auto &e : ids) res -= (e >= l && e <= r);
            return res;
        };
		ll _start = ask(n, adj, nodes, 0, nodes.size()-1, n);
		ll start = ask(n, adj, nodes, 0, nodes.size()-1, col);
		while (start != _start) {
			ll l = 0, r = nodes.size()-1;
			while (l < r) {
				ll mid = l + (r - l) / 2;
				if (count_rem(mid+1, r) == 0) { r = mid; continue; }
				if (count_rem(l, mid) == 0) { l = mid + 1; continue; }
				auto opt = recent(l, mid);
				if (!opt) {
					ll _q = ask(n, adj, nodes, l, mid, n);
					ll q = ask(n, adj, nodes, l, mid, col);
					if (q != _q) r = mid;
					else l = mid + 1;
				}
				else {
					ll prev = ask(n, adj, nodes, l, mid, n, without(opt.value()));
					ll nw = ask(n, adj, nodes, l, mid, n, ids);
					if (nw >= prev) r = mid;
					else { // opt.value() is isolated
						ll _nw = ask(n, adj, nodes, l, mid, col);
						if (nw != _nw) r = mid;
						else l = mid + 1;
					}
				}
			}
			res[nodes[l]] = col;
			ids.push_back(l);
			_start = ask(n, adj, nodes, 0, nodes.size()-1, n, ids);
		}
	}
}
vector<int> find_colours(int n, vector<int> u, vector<int> v) {
	int m = u.size();
	vector<vector<ll>> adj(n);
	for (ll i = 0; i < m; i++) {
		adj[u[i]].push_back(v[i]);
		adj[v[i]].push_back(u[i]);
	}
	vector<ll> red(n);
	for (ll i = 0; i < n; i++) {
		red[i] = true;
		for (auto &e : adj[i]) if (red[e]) red[i] = false;
	}
	vector<int> res(n, -1);
	solve_red(n, adj, res, red);
	solve_blue(n, adj, res, red);
	return res;
}
#ifdef TEST
#include "grader.cpp"
#endif
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |