제출 #240638

#제출 시각아이디문제언어결과실행 시간메모리
240638faremy건물 4 (JOI20_building4)C++14
100 / 100
498 ms71944 KiB
#include <iostream> #include <algorithm> #include <vector> const int MAXN = 1e6 + 2; const int INFTY = 2e9; int plan[2][MAXN]; int color[MAXN]; struct Ans { Ans() : size(-INFTY), pos(-1), prev(-1) {} Ans(int s, int p, int pr) : size(s), pos(p), prev(pr) {}; int size, pos, prev; bool operator >(const Ans &other) const { return (size > other.size); } } lis[2][MAXN]; std::vector<int> findlis(int size) { std::fill_n((Ans *)lis, 2 * MAXN, Ans()); lis[0][0] = Ans(0, 0, -1); for (int iPos = 1; iPos <= size; iPos++) { Ans b0 = lis[0][iPos - 1]; Ans b1 = lis[1][iPos - 1]; if (plan[0][iPos - 1] <= plan[1][iPos] && b0 > lis[1][iPos]) lis[1][iPos] = b0; if (plan[1][iPos - 1] <= plan[1][iPos] && b1 > lis[1][iPos]) lis[1][iPos] = b1; b0.size++; b1.size++; b0.prev = b0.pos; b1.prev = b1.pos; b0.pos = b1.pos = iPos; if (plan[0][iPos - 1] <= plan[0][iPos] && b0 > lis[0][iPos]) lis[0][iPos] = b0; if (plan[1][iPos - 1] <= plan[0][iPos] && b1 > lis[0][iPos]) lis[0][iPos] = b1; } std::vector<int> seq; int pos = size; while (pos != -1) { seq.emplace_back(pos); pos = lis[0][pos].prev; } if (seq.back() != 0) return {}; std::vector<int> choice; pos = 0; while (seq.size() > 1) { choice.emplace_back(0); seq.pop_back(); for (pos++; pos < seq.back(); pos++) choice.emplace_back(1); } choice.emplace_back(0); return choice; } int cnt0(std::vector<int> vec) { int c = 0; for (int i : vec) c += (i == 0); return c - 2; } int main() { std::ios::sync_with_stdio(false); std::cout.tie(nullptr); std::cin.tie(nullptr); int half; std::cin >> half; int build = half * 2; for (int iPlan = 0; iPlan < 2; iPlan++) { plan[iPlan][build + 1] = INFTY; for (int iBuild = 1; iBuild <= build; iBuild++) std::cin >> plan[iPlan][iBuild]; } std::vector<int> choiceA = findlis(build + 1); for (int iBuild = 1; iBuild <= build; iBuild++) std::swap(plan[0][iBuild], plan[1][iBuild]); std::vector<int> choiceB = findlis(build + 1); if (choiceA.empty() || choiceB.empty()) { std::cout << "-1\n"; return 0; } for (int &choose : choiceB) choose ^= 1; choiceB[0] = choiceB[build + 1] = 0; int maxA = cnt0(choiceA); int minA = cnt0(choiceB); if (maxA < half || minA > half) { std::cout << "-1\n"; return 0; } std::vector<int> eq; for (int iPos = 0; iPos < build + 2; iPos++) if (choiceA[iPos] == choiceB[iPos]) eq.emplace_back(iPos); for (int iSpl = 0; maxA > half; iSpl++) { int chg = 0; for (int iPos = eq[iSpl] + 1; iPos < eq[iSpl + 1]; iPos++) chg += choiceA[iPos] - choiceB[iPos]; if (maxA + chg >= half) { maxA += chg; for (int iPos = eq[iSpl] + 1; iPos < eq[iSpl + 1]; iPos++) choiceA[iPos] ^= 1; continue; } for (int iPos = eq[iSpl] + 1; iPos < eq[iSpl + 1]; iPos++) color[iPos] = (plan[choiceA[iPos]][iPos] < plan[choiceB[iPos]][iPos]); for (int iPos = eq[iSpl] + 1; iPos < eq[iSpl + 1] && maxA > half; iPos++) if (color[iPos] == 1) { maxA += choiceA[iPos] - choiceB[iPos]; choiceA[iPos] ^= 1; } for (int iPos = eq[iSpl + 1] - 1; iPos > eq[iSpl] && maxA > half; iPos--) if (color[iPos] == 0) { maxA += choiceA[iPos] - choiceB[iPos]; choiceA[iPos] ^= 1; } } for (int iPos = 1; iPos <= build; iPos++) std::cout << (char)('A' + choiceA[iPos]); std::cout << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...