Submission #1303738

#TimeUsernameProblemLanguageResultExecution timeMemory
1303738gs14004Teoretičar (COCI18_teoreticar)C++17
130 / 130
3062 ms103144 KiB
#include <bits/stdc++.h> #define sz(v) ((int)(v).size()) #define all(v) (v).begin(), (v).end() #define cr(v, n) (v).clear(), (v).resize(n); using namespace std; using lint = long long; using pi = array<int, 2>; vector<int> split(int n, vector<pi> edges) { if (sz(edges) == 0) return {}; vector<vector<int>> gph(n); vector<int> nxt(sz(edges) * 2), vis(sz(edges) * 2); for (int i = 0; i < sz(edges); i++) { auto [u, v] = edges[i]; v += n / 2; gph[u].push_back(2 * i); gph[v].push_back(2 * i + 1); } for (int i = 0; i < n; i++) { for (int j = 0; j < sz(gph[i]); j += 2) { nxt[gph[i][j]] = (gph[i][j + 1] ^ 1); nxt[gph[i][j + 1]] = (gph[i][j] ^ 1); } } vector<int> ans; for (int i = 0; i < sz(edges) * 2; i++) { if (!vis[i]) { for (int j = i; !vis[j]; j = nxt[j]) { ans.push_back(j); vis[j] = vis[j ^ 1] = 1; } } } return ans; } vector<int> EdgeColoringRegular(int n, int k, vector<pi> edges) { /*cerr << n << " " << k << " " << sz(edges) << endl; for (auto &[u, v] : edges) cout << u << " " << v << endl;*/ assert(k > 0); if (k == 1) { return vector<int>(sz(edges)); } if (k % 2 == 0) { auto decomp = split(2 * n, edges); vector<pi> sub[2]; for (int i = 0; i < sz(decomp); i++) { sub[i % 2].push_back(edges[decomp[i] / 2]); } vector<int> rec[2]; rec[0] = EdgeColoringRegular(n, k / 2, sub[0]); rec[1] = EdgeColoringRegular(n, k / 2, sub[1]); vector<int> ans(sz(edges)); for (int i = 0; i < sz(decomp); i++) { ans[decomp[i] / 2] = rec[i % 2][i / 2] + (i % 2) * (k / 2); } return ans; } int t = 0; while ((1 << t) < k * n) t++; vector<array<int, 4>> todnc; int alph = (1 << t) / k; int beta = (1 << t) - k * alph; // < k for (int i = 0; i < sz(edges); i++) { todnc.push_back({edges[i][0], edges[i][1] + n, alph, i}); } if (beta > 0) { for (int i = 0; i < n; i++) { todnc.push_back({i, i + n, beta, -1}); } } for (int i = 0; i < t; i++) { vector<pi> toeuler; vector<array<int, 4>> sub[2]; for (auto &[u, v, k, idx] : todnc) { if (k % 2) toeuler.push_back({u, v - n}); } sub[1] = sub[0]; auto pth = split(2 * n, toeuler); vector<int> parity(sz(toeuler)); for (int i = 1; i < sz(pth); i += 2) parity[pth[i] / 2] = 1; int ptr = 0, bal = 0; for (auto &[u, v, k, idx] : todnc) { int l = k / 2, r = k / 2; if (k % 2) { if (parity[ptr++]) r++; else l++; } if (idx == -1) bal += l - r; if (l) sub[0].push_back({u, v, l, idx}); if (r) sub[1].push_back({u, v, r, idx}); } if (bal >= 0) todnc = sub[1]; else todnc = sub[0]; } vector<int> ans(sz(edges), -1); for (auto &[u, v, z, idx] : todnc) { assert(z == 1 && idx != -1); ans[idx] = k - 1; } vector<pi> sub; for (int i = 0; i < sz(edges); i++) { if (ans[i] == -1) sub.push_back(edges[i]); } int piv = 0; auto sol = EdgeColoringRegular(n, k - 1, sub); for (int i = 0; i < sz(edges); i++) { if (ans[i] == -1) ans[i] = sol[piv++]; } return ans; } vector<int> EdgeColoring(int l, int r, vector<pi> edges) { if (sz(edges) == 0) return vector<int>(); vector<int> d[2]; cr(d[0], l); cr(d[1], r); for (auto &[x, y] : edges) d[0][x]++, d[1][y]++; int k = max(*max_element(all(d[0])), *max_element(all(d[1]))); for (int i = 0; i < 2; i++) { vector<int> ord(l); iota(all(ord), 0); sort(all(ord), [&](int x, int y) { return d[i][x] < d[i][y]; }); vector<int> maps(l); int nl = 0; for (int j = 0; j < sz(ord);) { int nxt = j, sum = 0; while (nxt < sz(ord) && sum + d[i][ord[nxt]] <= k) { sum += d[i][ord[nxt]]; maps[ord[nxt]] = nl; nxt++; } nl++; j = nxt; } for (auto &e : edges) { e[i] = maps[e[i]]; } l = nl; swap(l, r); } int n = max(l, r); cr(d[0], n); cr(d[1], n); for (auto &[x, y] : edges) d[0][x]++, d[1][y]++; int j = 0; int orig = sz(edges); for (int i = 0; i < n; i++) { while (d[0][i] < k) { while (d[1][j] == k) j++; edges.push_back({i, j}); d[0][i]++; d[1][j]++; } } auto sol = EdgeColoringRegular(n, k, edges); sol.resize(orig); return sol; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int l, r, m; cin >> l >> r >> m; vector<pi> edges(m); for (auto &[x, y] : edges) cin >> x >> y, x--, y--; auto ed = EdgeColoring(l, r, edges); cout << *max_element(all(ed)) + 1 << "\n"; for (auto &x : ed) cout << x + 1 << "\n"; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...