Submission #705062

#TimeUsernameProblemLanguageResultExecution timeMemory
705062CyanmondMonster Game (JOI21_monster)C++17
100 / 100
104 ms980 KiB
#include "monster.h" #include <bits/stdc++.h> namespace monster{ int N; std::map<std::pair<int, int>, int> memo; bool ask(int a, int b) { bool isSw = false; if (a > b) { isSw = true; std::swap(a, b); } if (memo.find({a, b}) == memo.end()) { memo[{a, b}] = Query(a, b); } return memo[{a, b}] ^ isSw; } std::vector<int> Solve(int n_) { N = n_; std::vector<int> res(N); std::iota(res.begin(), res.end(), 0); auto mergeSort = [&](auto &&self, int l, int r) -> void { if (r - l == 1) { return; } const int m = (l + r) / 2; self(self, l, m); self(self, m, r); std::vector<int> lVec, rVec; std::copy(res.begin() + l, res.begin() + m, std::back_inserter(lVec)); std::copy(res.begin() + m, res.begin() + r, std::back_inserter(rVec)); std::vector<int> mergedVec; int i = 0, j = 0; while (i != m - l and j != r - m) { if (not ask(lVec[i], rVec[j])) { mergedVec.push_back(lVec[i++]); } else { mergedVec.push_back(rVec[j++]); } } if (i != m - l) { std::copy(lVec.begin() + i, lVec.end(), std::back_inserter(mergedVec)); } if (j != r - m) { std::copy(rVec.begin() + j, rVec.end(), std::back_inserter(mergedVec)); } std::copy(mergedVec.begin(), mergedVec.end(), res.begin() + l); }; mergeSort(mergeSort, 0, N); std::vector<bool> isF(N); isF[0] = true; int l = -1, r = -1; // find the first block! std::vector<int> countWin; for (int i = 0; i < std::min(N, 20); ++i) { int c = 0; for (int j = 0; j < std::min(N, 20); ++j) { if (i == j) continue; if (ask(res[i], res[j])) { ++c; } } if (i == 0 or countWin.back() >= c) { countWin.push_back(c); } else { break; } } if (countWin.size() == 1) { l = 0; r = 1; } else if (countWin.size() == 2) { assert(countWin[0] == countWin[1] and countWin[0] == 1); if (not ask(res[0], res[1])) { l = 0; r = 2; } else { isF[1] = true; l = 1; r = 2; } } else { l = 0; r = (int)countWin.size(); } while (r != N) { isF[r] = true; bool fin = false; for (int i = r; i < N; ++i) { if (ask(res[l], res[i])) { fin = true; l = r; r = i + 1; break; } } if (not fin) { break; } } std::vector<int> answer; std::stack<int> stk; for (int i = 0; i < N; ++i) { if (isF[i]) { while (not stk.empty()) { answer.push_back(stk.top()); stk.pop(); } } stk.push(res[i]); } while (not stk.empty()) { answer.push_back(stk.top()); stk.pop(); } memo.clear(); std::vector<int> tet(N); for (int i = 0; i < N; ++i) { tet[answer[i]] = i; } return tet; } } std::vector<int> Solve(int n_) { return monster::Solve(n_); } /* #include <cstdio> #include <cstdlib> using std::exit; using std::fprintf; using std::printf; using std::scanf; constexpr int Q_MAX = 25000; constexpr int N_MAX = 1'000; int N; int S[N_MAX]; int query_count = 0; void WrongAnswer(int code) { printf("Wrong Answer [%d]\n", code); exit(0); } bool Query(int a, int b) { if (++query_count > Q_MAX) WrongAnswer(6); if (a < 0 || N <= a || b < 0 || N <= b) WrongAnswer(4); if (a == b) WrongAnswer(5); return (S[a] > S[b]) ^ (abs(S[a] - S[b]) == 1); } void main_() { if (scanf("%d", &N) != 1) { fprintf(stderr, "Error while reading.\n"); exit(1); } for (int i = 0; i < N; i++) { if (scanf("%d", S + i) != 1) { fprintf(stderr, "Error while reading.\n"); exit(1); } } N = 1000; int cas = 1000; std::mt19937 mt(100); std::uniform_int_distribution dist(1, N); std::vector<int> A(N); std::iota(A.begin(), A.end(), 0); int mav = 0; while (cas--) { std::shuffle(A.begin(), A.end(), mt); for (int i = 0; i < N; ++i) S[i] = A[i]; const auto T = Solve(N); if (T != A) { std::cout << "bad" << std::endl; } mav = std::max(mav, query_count); query_count = 0; } std::cout << mav << std::endl; std::vector<int> T = Solve(N); if ((int)T.size() != N) WrongAnswer(1); for (int i = 0; i < N; ++i) { std::cout << S[T[i]] << ' '; } std::cout << std::endl; for (int i = 0; i < N; i++) { if (T[i] < 0 || N <= T[i]) WrongAnswer(2); if (T[i] != S[i]) WrongAnswer(3); } printf("Accepted: %d\n", query_count); return; } int main() { main_(); }*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...