Submission #1079669

#TimeUsernameProblemLanguageResultExecution timeMemory
1079669skittles1412Highway Tolls (IOI18_highway)C++17
90 / 100
213 ms18096 KiB
#include "bits/extc++.h" using namespace std; template <typename T, typename... U> void dbgh(const T& t, const U&... u) { cerr << t; ((cerr << " | " << u), ...); cerr << endl; } #ifdef DEBUG #define dbg(...) \ cerr << "L" << __LINE__ << " [" << #__VA_ARGS__ << "]: "; \ dbgh(__VA_ARGS__) #else #define dbg(...) #define cerr \ if (false) \ cerr #endif using ll = long long; #define endl "\n" #define long int64_t #define sz(x) int(std::size(x)) inline void init_io() { cin.tie(nullptr); cin.exceptions(ios::failbit); ios_base::sync_with_stdio(false); } template <typename T> vector<T> iota(int n, T x) { vector<T> ans(n); iota(begin(ans), end(ans), x); return ans; } template <typename T> vector<T>& operator+=(vector<T>& a, const vector<T>& b) { a.insert(end(a), begin(b), end(b)); return a; } template <typename T> vector<T> operator+(vector<T> a, const vector<T>& b) { return a += b; } template <typename Cb> struct CmpByKey { Cb cb; CmpByKey(Cb cb) : cb(cb) {} template <typename T> bool operator()(const T& a, const T& b) const { return cb(a) < cb(b); } }; template <typename T, typename Cb> T first_true(T l, T r, const Cb& cb) { while (l < r) { T mid = (l + r) / 2; if (cb(mid)) { r = mid; } else { l = mid + 1; } } return l; } template <typename T, typename Cb> T last_true(T l, T r, const Cb& cb) { while (l < r) { T mid = (l + r + 1) / 2; if (cb(mid)) { l = mid; } else { r = mid - 1; } } return l; } template <typename T> ostream& operator<<(ostream& out, const vector<T>& arr) { out << "["; for (int i = 0; i < sz(arr); i++) { if (i) { out << ", "; } out << arr[i]; } return out << "]"; } template <typename T> T negated(T arr) { for (auto& a : arr) { a = -a; } return arr; } template <typename A, typename B> ostream& operator<<(ostream& out, const pair<A, B>& p) { return out << "(" << p.first << ", " << p.second << ")"; } inline vector<int> inverse(const vector<int>& arr) { int n = sz(arr); vector<int> ans(n); for (int i = 0; i < n; i++) { ans[arr[i]] = i; } return ans; } ll ask(const std::vector<int>& w); void answer(int s, int t); mt19937_64 cowng(1412); struct G { int m; vector<int> perm, iperm; G() {} G(int m) : m(m) { perm = iota(m, 0); shuffle(begin(perm), end(perm), cowng); iperm = inverse(perm); } long query(const vector<int>& arr) const { vector<int> ans(m); for (int i = 0; i < m; i++) { ans[i] = arr[perm[i]]; } return ask(ans); } void submit(int u, int v) const { answer(u, v); } } G; pair<vector<int>, vector<pair<int, int>>> bfs(const vector<vector<int>>& graph, int src) { int n = sz(graph); vector dist(n, -1); queue<int> q; vector<pair<int, int>> tedges; auto push = [&](int u, int src, int d) -> void { if (dist[u] != -1) { return; } dist[u] = d; q.push(u); if (src != -1) { tedges.emplace_back(src, u); } }; push(src, -1, 0); while (sz(q)) { int u = q.front(); q.pop(); for (auto& v : graph[u]) { push(v, u, dist[u] + 1); } } return {dist, tedges}; } void solve(int n, const vector<pair<int, int>>& edges, int wa, int) { int m = sz(edges); dbg(m); vector<vector<pair<int, int>>> graph(n); for (int i = 0; i < m; i++) { auto& [u, v] = edges[i]; graph[u].emplace_back(v, i); graph[v].emplace_back(u, i); } long base = G.query(vector<int>(m, 0)); auto nodes_blocked = [&](const vector<int>& nodes) -> vector<int> { vector<int> cv(m); for (auto& u : nodes) { for (auto& [_v, ei] : graph[u]) { cv[ei] = true; } } return cv; }; auto ask_nodes = [&](const vector<int>& nodes) -> bool { return G.query(nodes_blocked(nodes)) > base; }; int root = first_true(0, n, [&](int x) -> bool { return ask_nodes(iota(x + 1, 0)); }); dbg(root); auto base_block = iota(root, 0); dbg(base_block); auto [dist, tedges] = bfs([&]() { vector<vector<int>> graph(n); for (auto& [u, v] : edges) { if (u >= root && v >= root) { graph[u].push_back(v); graph[v].push_back(u); } } return graph; }(), root); dbg(tedges); auto ord = iota(n, 0); sort(begin(ord), end(ord), CmpByKey([&](int u) -> int { return dist[u]; })); int u1_ind = last_true(0, n, [&](int x) -> bool { return ask_nodes(base_block + vector(begin(ord) + x, end(ord))); }), u1 = ord[u1_ind]; if (dist[u1] == base / wa) { G.submit(u1, root); return; } dbg(u1); vector<int> rem_nodes; { vector<vector<int>> graph(n); for (auto& [u, v] : tedges) { graph[u].push_back(v); graph[v].push_back(u); } vector<bool> vis(n); vector<int> q; for (int i = 0; i <= root; i++) { vis[i] = true; } auto push = [&](int u) -> void { if (vis[u]) { return; } vis[u] = true; q.push_back(u); }; push(u1); while (sz(q)) { int u = q.back(); q.pop_back(); for (auto& v : graph[u]) { push(v); } } for (auto& a : ord) { if (!vis[a]) { rem_nodes.push_back(a); } } } int u2_ind = last_true(0, sz(rem_nodes), [&](int x) -> bool { return ask_nodes(base_block + vector(begin(rem_nodes) + x, end(rem_nodes))); }), u2 = rem_nodes[u2_ind]; dbg(u1, u2); dbg(ord, u1_ind, u2_ind); G.submit(u1, u2); } void find_pair(int n, vector<int> edges_u, vector<int> edges_v, int wa, int wb) { int m = sz(edges_u); G = m; return solve(n, [&]() { vector<pair<int, int>> cv(m); for (int i = 0; i < m; i++) { cv[G.perm[i]] = {edges_u[i], edges_v[i]}; } return cv; }(), wa, wb); }
#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...