Submission #753717

#TimeUsernameProblemLanguageResultExecution timeMemory
753717StickfishCheerleaders (info1cup20_cheerleaders)C++17
100 / 100
553 ms5788 KiB
#include <iostream> #include <vector> #include <cassert> using ll = long long; using namespace std; ll get_inversion(vector<int>& p) { int n = p.size(); ll ans = 0; for (int i = 0; i < n; ++i) for (int j = i + 1; j < n; ++j) { ans += p[i] > p[j]; } return ans; } vector<int> combine_permutations(vector<int> a, vector<int> b) { int n = a.size(); vector<int> ans(n); for (int i = 0; i < n; ++i) { ans[i] = b[a[i]]; } return ans; } vector<int> reverse_permutation(vector<int> a) { int n = a.size(); vector<int> ans(n); for (int i = 0; i < n; ++i) ans[a[i]] = i; return ans; } ll get_inv_block(vector<int>::iterator begin, vector<int>::iterator end) { int n = end - begin; auto mid = begin + n / 2; vector<int> cless(n, 0); for (auto it = mid; it < end; ++it) { ++cless[*it]; } for (int i = 1; i < n; ++i) cless[i] += cless[i - 1]; ll ans = 0; for (auto it = begin; it < mid; ++it) { ans += cless[*it]; } return ans; } void split_into_halves(vector<int>::iterator begin, vector<int>::iterator end) { int n = end - begin; auto mid = begin + n / 2; vector<int> pos0(n, 0); vector<int> pos1(n, 0); for (auto it = begin; it < end; ++it) { if (it < mid) ++pos0[*it]; else ++pos1[*it]; } --pos0[0]; --pos1[0]; for (int i = 1; i < n; ++i) { pos0[i] += pos0[i - 1]; pos1[i] += pos1[i - 1]; } for (auto it = begin; it < end; ++it) { if (it < mid) it[0] = pos0[*it]; else it[0] = pos1[*it]; } } pair<ll, string> get_ans(vector<int> p) { int n = p.size(); ll ans = 0; int ansx = 0; for (int bt = n / 2; bt > 0; bt /= 2) { ll inv0 = 0; for (auto it = p.begin(); it < p.end(); it += bt * 2) { inv0 += get_inv_block(it, it + bt * 2); split_into_halves(it, it + bt * 2); } ll inv1 = 1ll * (n / 2) * bt - inv0; if (inv1 < inv0) { ans += inv1; vector<int> op(n); for (int i = 0; i < n; ++i) op[i] = i ^ bt; p = combine_permutations(op, p); ansx += bt; } else { ans += inv0; } } string ansa = ""; for (int bt = 1; bt < n; bt *= 2) { ansa.push_back('2'); if (ansx & bt) ansa.push_back('1'); } return {ans, ansa}; } signed main() { int N; cin >> N; int m = (1 << N); vector<int> p(m); for (int i = 0; i < m; ++i) cin >> p[i]; if (N == 0) { cout << "0\n"; cout << "1\n"; return 0; } vector<int> op1(m); vector<int> op2(m); for (int i = 0; i < m; ++i) { op1[i] = i ^ (m / 2); op2[i] = (i >> 1) + ((i & 1) << (N - 1)); } op2 = reverse_permutation(op2); //for (int i = 0; i < m; ++i) //cout << op2[i] << ' '; //cout << endl; ll ans = 1ll * m * m;; string ansa; string curst = ""; for (int t = 0; t < N; ++t) { auto [nans, nansa] = get_ans(p); if (nans < ans) { ans = nans; ansa = curst + nansa; } p = combine_permutations(op2, p); curst.push_back('2'); } cout << ans << '\n'; cout << ansa << '\n'; //for (int i = 0; i < m; ++i) //cout << p[i] << ' '; //cout << endl; //for (auto x : ansa) { //if (x == '1') //p = combine_permutations(op1, p); //else //p = combine_permutations(op2, p); //} //for (int i = 0; i < m; ++i) //cout << p[i] << ' '; //cout << endl; //cout << get_inversion(p) << endl; //assert(get_inversion(p) == ans); }
#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...