Submission #830259

#TimeUsernameProblemLanguageResultExecution timeMemory
830259GusterGoose27Split the Attractions (IOI19_split)C++17
18 / 100
2083 ms19012 KiB
#pragma GCC optimize("unroll-loops") #include "split.h" #include <bits/stdc++.h> using namespace std; typedef pair<int, int> pii; const int MAXN = 1e5+5; int n, m; // vector<int> edges[MAXN]; vector<int> tree[MAXN]; pii elist[2*MAXN]; vector<int> res; // bool vis[MAXN]; int uf[MAXN]; int rnk[MAXN]; int sz[MAXN]; void perm(vector<int> &a, mt19937 &gen) { for (int i = 1; i < a.size(); i++) swap(a[i], a[gen()%(i+1)]); } void perm(pii a[], mt19937 &gen) { for (int i = 1; i < m; i++) swap(a[i], a[gen()%(i+1)]); } int dfs(int cur, int a, int b, int p = -1) { sz[cur] = 1; // vis[cur] = 1; int ans = -1; for (int nxt: tree[cur]) { if (nxt == p) continue; ans = max(dfs(nxt, a, b, cur), ans); sz[cur] += sz[nxt]; } if (sz[cur] >= a && n-sz[cur] >= b) ans = 2*cur; else if (sz[cur] >= b && n-sz[cur] >= a) ans = 2*cur+1; return ans; } void assign(int cur, int spec, bool val, int a[2], int p = -1) { if (cur == spec) val ^= 1; if (a[val]) { res[cur] = val; a[val]--; } for (int nxt: tree[cur]) { if (nxt == p) continue; assign(nxt, spec, val, a, cur); } } int find(int i) { return uf[i] == -1 ? i : uf[i] = find(uf[i]); } void merge(int a, int b) { a = find(a); b = find(b); if (rnk[a] < rnk[b]) swap(a, b); uf[b] = a; if (rnk[a] == rnk[b]) rnk[a]++; } bool test(int a, int b, mt19937 &gen, int s) { for (int i = 0; i < n; i++) { tree[i].clear(); // perm(edges[i], gen); } // trial 2: kruskal memset(rnk, 0, sizeof(int)*n); fill(uf, uf+n, -1); perm(elist, gen); for (int i = 0; i < m; i++) { if (find(elist[i].first) != find(elist[i].second)) { merge(elist[i].first, elist[i].second); tree[elist[i].first].push_back(elist[i].second); tree[elist[i].second].push_back(elist[i].first); } } int ans = dfs(s, a, b); if (ans == -1) return 0; // memset(vis, 0, sizeof(bool)*n); res = vector<int>(n, 2); int cur[2]; cur[0] = a; cur[1] = b; assign(s, ans/2, (ans&1)^1, cur); return 1; } vector<int> find_split(int N, int a, int b, int c, vector<int> p, vector<int> q) { n = N; m = p.size(); vector<pii> change({{a, 1}, {b, 2}, {c, 3}}); sort(change.begin(), change.end()); a = change[0].first; b = change[1].first; for (int i = 0; i < m; i++) { // edges[p[i]].push_back(q[i]); // edges[q[i]].push_back(p[i]); elist[i] = pii(p[i], q[i]); } bool f = 0; mt19937 gen(0); for (int i = 0; i < 100000; i++) { // perm(edges[i%n], gen); // perm(edges[(i+n/2)%n], gen); if (test(a, b, gen, i%n)) { f = 1; break; } } if (f) for (int i = 0; i < n; i++) res[i] = change[res[i]].second; else res = vector<int>(n, 0); return res; }

Compilation message (stderr)

split.cpp: In function 'void perm(std::vector<int>&, std::mt19937&)':
split.cpp:25:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   25 |  for (int i = 1; i < a.size(); i++) swap(a[i], a[gen()%(i+1)]);
      |                  ~~^~~~~~~~~~
#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...