제출 #606282

#제출 시각아이디문제언어결과실행 시간메모리
606282drdilyorICC (CEOI16_icc)C++17
100 / 100
132 ms632 KiB
#include <bits/stdc++.h> #ifdef ONPC #include "t_debug.cpp" #else #define debug(...) 42 #include "icc.h" #endif #define sz(a) ((int)(a).size()) using namespace std; using ll = long long; const int INF = 1e9; const ll INFL = 1e18; const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count(); mt19937 rng(123); template<typename T, typename U> istream& operator>>(istream& is, pair<T, U>& p) { return is >> p.first >> p.second; } const int N = 100, LOGN = 17, MOD = 1e9+7; int nextPower2(int n) { n--; n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; n |= n >> 16; return 1+n; } struct DSU { int n; vector<int> parent; vector<int> size; vector<vector<int>> full; DSU(int n) : n(n), parent(n), size(n, 1), full(n) { for (int i = 0; i < n; i++) { parent[i] = i; full[i] = {i}; } } int get(int i) { return parent[i] == i ? i : parent[i] = get(parent[i]); } void merge(int v, int u) { v = get(v); u = get(u); if (u == v) return; if (size[v] < size[u]) swap(v, u); parent[u] = v; size[v] += size[u]; for (int j : full[u]) { full[v].push_back(j); } } inline vector<int> elems(int i) { return full[get(i)]; } }; #ifdef ONPC void setRoad(int u, int v); #endif void confirm(int u, int v); int query(vector<int>&, vector<int>&); int query(vector<int>&&, vector<int>&&); int myrand(int i) { return rng() % i; } void run(int n) { DSU cc(n); for (int e = 0; e < n-1; e++) { vector<vector<int>> comps; vector<int> visited(n); for (int i = 0; i < n; i++) { if (visited[cc.get(i)]) continue; comps.push_back(cc.full[cc.get(i)]); visited[cc.get(i)] = true; } sort(comps.begin(), comps.end(), [&](const vector<int>& a, const vector<int>& b) { return a.size() < b.size();}); debug(cc.parent, cc.full); debug(comps); vector<int> a, b; bool found = false; vector<int> offs; for (int off =nextPower2(sz(comps)) >> 1; off; off >>= 1) { offs.push_back(off); } random_shuffle(offs.begin(), offs.end(), myrand); function<tuple<vector<int>,vector<int>>(int)> partition = [&](int off) { vector<int> a, b; for (int i = 0; i < sz(comps); i++) { if (i / off % 2 == 0) { for (int j : comps[i]) a.push_back(j); } else { for (int j : comps[i]) b.push_back(j); } } return tuple<vector<int>,vector<int>>{a, b}; }; for (int i = 0; i < sz(offs)-1; i++) { tie(a, b) = partition(offs[i]); if (query(a, b)) {found = true;break;} } if (!found) { tie(a, b) = partition(offs.back()); } while (sz(a) > 1) { vector<int> a2; for (int i = 0; i < sz(a) / 2; i++) { a2.push_back(a[i]); } debug(a, a2); if (!query(a2, b)) { a2.clear(); for (int i = sz(a) / 2; i < sz(a); i++) { a2.push_back(a[i]); } } a = a2; } while (sz(b) > 1) { vector<int> b2; for (int i = 0; i < sz(b) / 2; i++) { b2.push_back(b[i]); } if (!query(b2, a)) { b2.clear(); for (int i = sz(b) / 2; i < sz(b); i++) { b2.push_back(b[i]); } } b = b2; } cc.merge(a.front(), b.front()); confirm(a.front(), b.front()); } } #ifdef ONPC int n, m; bool adj[N][N]; vector<pair<int,int>> edges; int cur = 0; int query_count = 0; int query(vector<int>& a, vector<int>& b) { ++query_count; bool res = false; for (int i : a) { for (int j : b) { assert(i != j); if (adj[i][j])res = true; } } return res; } void advance() { if (cur < sz(edges)) { auto [u,v] = edges[cur]; adj[u][v] = adj[v][u] = true; cur++; } } void setRoad(int u, int v) { if (u > v) swap(u, v); if (edges[cur-1].first != u || edges[cur-1].second != v) { debug("wrong guess", cur, edges[cur-1], u, v); } advance(); } int solve() { cin >> n >> m; if (!cin) return 1; memset(adj, 0, sizeof(adj)); edges.clear(); for (int i = 0; i < n-1; i++) { int u, v; cin >> u >> v; if (u > v) swap(u, v); edges.emplace_back(u, v); } debug(edges); advance(); run(n); assert(cur == n-1); debug(query_count); return 0; } signed main() { cin.tie(0)->sync_with_stdio(0); int t = 1; #ifdef ONPC t = 10000; #endif while (t-- && cin) { if (solve()) break; #ifdef ONPC cout << "____________________" << endl; #endif } return 0; } #else int query(vector<int>& a, vector<int>& b) { vector<int> a2 = a, b2 = b; for (auto& i : a2) i++; for (auto& i : b2) i++; return query(a.size(), b.size(), a2.data(), b2.data()); } #endif void confirm(int u, int v){ #ifndef ONPC u++; v++; #endif setRoad(u, v); } int query(vector<int>&& a, vector<int>&& b) { return query(a, b); } /* █████ █████ ███ ████ ▒▒███ ▒▒███ ▒▒▒ ▒▒███ ███████ ████████ ███████ ████ ▒███ █████ ████ ██████ ████████ ███▒▒███ ▒▒███▒▒███ ███▒▒███ ▒▒███ ▒███ ▒▒███ ▒███ ███▒▒███▒▒███▒▒███ ▒███ ▒███ ▒███ ▒▒▒ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒▒▒ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███ ▒▒████████ █████ ▒▒████████ █████ █████ ▒▒███████ ▒▒██████ █████ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒███ ▒▒▒▒▒▒ ▒▒▒▒▒ ███ ▒███ ▒▒██████ ▒▒▒▒▒▒ */

컴파일 시 표준 에러 (stderr) 메시지

icc.cpp: In function 'void run(int)':
icc.cpp:5:24: warning: statement has no effect [-Wunused-value]
    5 |     #define debug(...) 42
      |                        ^~
icc.cpp:85:9: note: in expansion of macro 'debug'
   85 |         debug(cc.parent, cc.full);
      |         ^~~~~
icc.cpp:5:24: warning: statement has no effect [-Wunused-value]
    5 |     #define debug(...) 42
      |                        ^~
icc.cpp:86:9: note: in expansion of macro 'debug'
   86 |         debug(comps);
      |         ^~~~~
icc.cpp:5:24: warning: statement has no effect [-Wunused-value]
    5 |     #define debug(...) 42
      |                        ^~
icc.cpp:122:13: note: in expansion of macro 'debug'
  122 |             debug(a, a2);
      |             ^~~~~
#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...