Submission #1208666

#TimeUsernameProblemLanguageResultExecution timeMemory
1208666k1r1t0Permutation Game (APIO25_permgame)C++20
100 / 100
18 ms532 KiB
#include <bits/stdc++.h> using namespace std; int Bob(vector<int> t); const int NN = 410; int MM; vector<int> g[NN], ord, Uu, Vv; bool used[NN]; int count_ones; vector<vector<int>> cycles(const vector<int> &p) { int n = (int) p.size(); vector<bool> used(n, false); vector<vector<int>> res; count_ones = 0; for (int i = 0; i < n; i++) { if (used[i]) continue; int t = i; vector<int> cur; do { cur.push_back(t); used[t] = true; t = p[t]; } while (t != i); if (cur.size() == 1) count_ones++; if (cur.size() != 1) res.push_back(cur); } return res; } void dfs(int v) { if (used[v]) return; used[v] = true; ord.push_back(v); for (int u : g[v]) dfs(u); } void upd(vector<int> t, vector<int> &p) { vector<int> val(MM); for (int i = 0; i < MM; i++) val[ord[i]] = t[i]; int edge = Bob(val); swap(p[val[Uu[edge]]], p[val[Vv[edge]]]); } void split(vector<int> t, vector<int> &p) { vector<int> cur; int k = (int) t.size() - MM; cur.push_back(0); for (int i = 0; i < MM / 2 - 1; i++) if (cur.back() % (2 * k - 2) == 0) cur.push_back(cur.back() + k); else cur.push_back(cur.back() + 1); cur.push_back(cur.back() + 1); cur.push_back(cur.back() - k); for (int i = 0; i < MM / 2 - 2; i++) if (cur.back() % (2 * k - 2) == 1) cur.push_back(cur.back() - k); else cur.push_back(cur.back() - 1); for (int i = 0; i < MM; i++) cur[i] = t[cur[i]]; upd(cur, p); } int Alice(int m, int e, vector<int> u, vector<int> v, int n, vector<int> p) { MM = m; Uu = u; Vv = v; if (m == 2) { for (int i = 0; i < n; i++) { int pos = -1; for (int j = 0; j < n; j++) if (p[j] == i) pos = j; if (pos == i) continue; Bob({i, pos}); swap(p[i], p[pos]); } return n; } int orig = 0; for (int i = 0; i < n; i++) if (p[i] == i) orig++; if (orig >= n - m + 1) return orig; for (int i = 0; i < e; i++) { g[u[i]].push_back(v[i]); g[v[i]].push_back(u[i]); } int maxdeg = 0, mindeg = 2; for (int i = 0; i < m; i++) { maxdeg = max(maxdeg, (int) g[i].size()); mindeg = min(mindeg, (int) g[i].size()); } if (maxdeg >= 3) return orig; for (int i = 0; i < m; i++) if ((int) g[i].size() == mindeg) { dfs(i); break; } if (mindeg <= 1 || (m % 2 == 0 && orig == n - m)) { while (orig < n - m + 1) { auto st = cycles(p); vector<int> cur; for (int i = 0; i < (int) st.size() && (int) cur.size() < m; i++) for (int j = 0; j < (int) st[i].size() && (int) cur.size() < m; j++) cur.push_back(st[i][j]); upd(cur, p); orig = 0; for (int i = 0; i < n; i++) if (p[i] == i) orig++; } return n - m + 1; } if (m % 2 == 1) { auto st = cycles(p); int opt = count_ones, sum = 0, k = 0; for (int i = 0; i < (int) st.size(); i++) if (st[i].size() % 2 == 1) opt++; else sum += st[i].size(); sort(begin(st), end(st), [&](auto x, auto y) { return x.size() > y.size(); }); for (int i = 0; i < (int) st.size() && sum < m; i++) if ((int) st[i].size() % 2 == 1) { k++; sum += (int) st[i].size(); } opt -= 2 * (k / 2); while (orig < opt) { vector<int> cur; for (int i = 0; i < (int) st.size(); i++) { if ((int) st[i].size() % 2 == 0) continue; if ((int) st[i].size() < m) continue; if ((int) st[i].size() == m) cur = st[i]; else { for (int j = 0; j < m; j += 2) cur.push_back(st[i][j]); for (int j = m - 2; j > 0; j -= 2) cur.push_back(st[i][j]); } upd(cur, p); goto fin; } for (int i = 0; i < (int) st.size(); i++) if ((int) st[i].size() % 2 == 0) for (int j = 0; j < (int) st[i].size(); j++) cur.push_back(st[i][j]); while ((int) cur.size() > m - 1) cur.pop_back(); for (int i = 0; i < (int) st.size(); i++) if ((int) st[i].size() % 2 == 1) for (int j = 0; j < (int) st[i].size(); j++) cur.push_back(st[i][j]); while ((int) cur.size() > m) cur.pop_back(); upd(cur, p); fin:; orig = 0; for (int i = 0; i < n; i++) if (p[i] == i) orig++; st = cycles(p); } return opt; } int opt = n - m - 1; auto st = cycles(p); while (orig < opt) { int all = 0; vector<int> cur; for (int i = 0; i < (int) st.size(); i++) if ((int) st[i].size() == m) { upd(st[i], p); goto fin1; } for (int i = 0; i < (int) st.size(); i++) if ((int) st[i].size() >= m + 2) { split(st[i], p); goto fin1; } for (int i = 0; i < (int) st.size(); i++) if ((int) st[i].size() > 2) all += (int) st[i].size(); if (all < m + 2) break; sort(begin(st), end(st), [&](auto x, auto y) { return x.size() < y.size(); }); for (int i = 0; i < (int) st.size() && (int) cur.size() < m; i++) if (st[i].size() > 2) for (int j = 0; j < (int) st[i].size() && (int) cur.size() < m; j++) cur.push_back(st[i][j]); upd(cur, p); fin1:; orig = 0; for (int i = 0; i < n; i++) if (p[i] == i) orig++; st = cycles(p); } orig = 0; for (int i = 0; i < n; i++) if (p[i] == i) orig++; st = cycles(p); while (orig < opt) { vector<int> cur; for (int i = 0; i < (int) st.size(); i++) if ((int) st[i].size() == m) { upd(st[i], p); goto fin2; } for (int i = 0; i < (int) st.size(); i++) if ((int) st[i].size() >= 2 * m - 1) { split(st[i], p); goto fin2; } if ((int) st.size() == 1) break; sort(begin(st), end(st), [&](auto x, auto y) { return x.size() > y.size(); }); for (int i = 0; i < (int) st.size(); i++) { for (int j = 0; j < (int) st[i].size(); j++) cur.push_back(st[i][j]); if (cur.size() >= m && st[i].size() == cur.size()) { while (cur.size() >= m) cur.pop_back(); } } upd(cur, p); fin2:; orig = 0; for (int i = 0; i < n; i++) if (p[i] == i) orig++; st = cycles(p); } orig = 0; for (int i = 0; i < n; i++) if (p[i] == i) orig++; st = cycles(p); while (orig < opt) { vector<int> cur; for (int i = 0; i < (int) st.size(); i++) if ((int) st[i].size() == m) { upd(st[i], p); goto fin3; } for (int i = 0; i < (int) st.size(); i++) if ((int) st[i].size() >= m + 2) { split(st[i], p); goto fin3; } sort(begin(st), end(st), [&](auto x, auto y) { return x.size() < y.size(); }); for (int i = 0; i < (int) st.size() && (int) cur.size() < m; i++) for (int j = 0; j < (int) st[i].size() && (int) cur.size() < m; j++) cur.push_back(st[i][j]); upd(cur, p); fin3:; orig = 0; for (int i = 0; i < n; i++) if (p[i] == i) orig++; st = cycles(p); } return opt; }
#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...