Submission #639345

#TimeUsernameProblemLanguageResultExecution timeMemory
639345piOOEPaint By Numbers (IOI16_paint)C++17
100 / 100
726 ms91080 KiB
#include <bits/stdc++.h> #include "paint.h" using namespace std; string solve_puzzle(string s, vector<int> c) { s = "__" + s + "__"; int n = s.size(), k = c.size(); vector<int> nxtWhite(n + 1, n), nxtBlack(n + 1, n), prvBlack(n + 1, -1); auto canWhite = [&](int l, int r) { //[l, r) assert(l < r); return nxtBlack[l] >= r; }; auto canBlack = [&](int l, int r) { //[l, r) assert(l < r); return nxtWhite[l] >= r; }; for (int i = n - 1; i > -1; --i) { nxtBlack[i] = nxtBlack[i + 1]; nxtWhite[i] = nxtWhite[i + 1]; if (s[i] == '_') { nxtWhite[i] = i; } else if (s[i] == 'X') { nxtBlack[i] = i; } } for (int i = 0; i < n; ++i) { if (i > 0) { prvBlack[i] = prvBlack[i - 1]; } if (s[i] == 'X') { prvBlack[i] = i; } } vector pref(k + 1, vector<bool>(n + 1)), suf(k + 1, vector<bool>(n + 1)); fill(pref[0].begin(), pref[0].begin() + nxtBlack[0], true), fill(suf[k].begin() + prvBlack[n - 1] + 1, suf[k].end(), true); vector<int> prefSum(k + 1), sufSum(k + 1); for (int i = 0; i < k; ++i) { prefSum[i + 1] = prefSum[i] + c[i]; } for (int i = k - 1; i > -1; --i) { sufSum[i] = sufSum[i + 1] + c[i]; } vector<int> lazyWhite(n + 1), lazyBlack(n + 1); auto setBlack = [&](int l, int r) { //[l, r) lazyBlack[l] += 1; lazyBlack[r] -= 1; // cout << l << " " << r << endl; if (l <= 3 && 3 < r) { // cout << "hey :)" << endl; } }; auto setWhite = [&](int l, int r) { //[l, r) lazyWhite[l] += 1; lazyWhite[r] -= 1; }; for (int i = 0; i < n; ++i) { if (s[i] == 'X') { setBlack(i, i + 1); } else if (s[i] == '_') { setWhite(i, i + 1); } } vector last(k + 1, vector<int>(n + 1, -1)); //last good iota(last[0].begin(), last[0].begin() + nxtBlack[0], 0); fill(last[0].begin() + nxtBlack[0], last[0].end(), nxtBlack[0] - 1); // cout << "pref:\n"; for (int i = 2; i < n - 2; ++i) { for (int j = 1; j <= k; ++j) { last[j][i] = last[j][i - 1]; int L = i - c[j - 1] + 1; if (L >= 0 && canBlack(L, i + 1) && s[L - 1] != 'X') { int p = last[j - 1][L - 2]; if (p != -1 && canWhite(p + 1, L)) { pref[j][i] = true; last[j][i] = i; } } // cout << pref[j][i] << " "; } // cout << endl; } // cout << endl; for (int i = 0; i <= k; ++i) { fill(last[i].begin(), last[i].end(), -1); } iota(last[k].begin() + prvBlack[n - 1] + 1, last[k].end(), prvBlack[n - 1] + 1); fill(last[k].begin(), last[k].begin() + prvBlack[n - 1] + 1, prvBlack[n - 1] + 1); // cout << "suf\n"; for (int i = n - 3; i > 1; --i) { for (int j = 0; j < k; ++j) { last[j][i] = last[j][i + 1]; int R = i + c[j]; if (R <= n && canBlack(i, R) && s[R] != 'X') { int p = last[j + 1][R + 1]; if (p != -1 && canWhite(R, p)) { suf[j][i] = true; last[j][i] = i; } } // cout << suf[j][i] << " "; } // cout << endl; } for (int j = 0; j < k; ++j) { vector<int> pntL(n); for (int i = 1; i < n; ++i) { auto goodL = [&]() { return pref[j][pntL[i]] && canWhite(pntL[i] + 1, i); }; if (i + c[j] - 1 < n && pref[j + 1][i + c[j] - 1]) { pntL[i] = pntL[i - 1]; while (pntL[i] < i - 1 && !goodL()) { ++pntL[i]; } } } vector<int> pntR(n, n - 1); for (int i = n - 2; i > 0; --i) { auto goodR = [&]() { return suf[j + 1][pntR[i]] && canWhite(i + c[j], pntR[i]); }; if (i + c[j] - 1 < n && pref[j + 1][i + c[j] - 1] && suf[j][i]) { pntR[i] = pntR[i + 1]; while (pntR[i] > i + c[j] - 1 && !goodR()) { --pntR[i]; } if (pntL[i] < i - 1 && pntR[i] < n) { setBlack(i, i + c[j]); setWhite(pntL[i] + 1, i); setWhite(i + c[j], pntR[i]); } } } } string ans(n, '?'); int sumWhite = 0, sumBlack = 0; for (int i = 0; i < n; ++i) { sumWhite += lazyWhite[i]; sumBlack += lazyBlack[i]; if (sumWhite && sumBlack) { ans[i] = '?'; } else if (sumWhite) { ans[i] = '_'; } else { assert(sumBlack); ans[i] = 'X'; } } return ans.substr(2, n - 4); }
#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...