Submission #873038

#TimeUsernameProblemLanguageResultExecution timeMemory
873038aykhnPaint By Numbers (IOI16_paint)C++17
100 / 100
516 ms335140 KiB
#include "paint.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod = 1e9 + 7; ll n, k; int dp1[200005][105][2], dp2[200005][105][2]; int prefX[200005], pref_[200005], exl[200005], exr[200005], pref[200005], cnt[200005]; string res = ""; ll add(ll a, ll b) { return (a + b) % mod; } ll mult(ll a, ll b) { return (a * b) % mod; } ll sub(ll a, ll b) { return (a - b + 10*mod) % mod; } ll getX(ll l, ll r) { r = min(r, n - 1); if (l > 0) return sub(prefX[r], prefX[l - 1]); return prefX[r]; } ll get_(ll l, ll r) { r = min(r, n - 1); if (l > 0) return sub(pref_[r], pref_[l - 1]); return pref_[r]; } string solve_puzzle(string s, vector<int> c) { n = s.length(); k = c.size(); for (ll i = 0; i < n; i++) { if (i) { prefX[i] = prefX[i - 1]; pref_[i] = pref_[i - 1]; } prefX[i] += (s[i] == 'X'); pref_[i] += (s[i] == '_'); } for (ll i = 0; i < n; i++) { if (s[i] == '.' || s[i] == 'X') { ll cnt_ = get_(i, i + c[0] - 1); ll cntX = (!i ? 0 : getX(0, i - 1)); ll flag = 1; if (1 == c.size() && i + c[0] < n && getX(i + c[0], n - 1)) flag = 0; if (!(!flag || cntX || cnt_ || i + c[0] - 1 >= n)) { if (i) dp1[i][0][0] = dp1[i - 1][0][1]; else dp1[i][0][0] = 1; } } if (s[i] == '.' || s[i] == '_') { ll cntX = (!i ? 0 : getX(0, i - 1)); if (cntX) continue; if (i) dp1[i][0][1] = dp1[i - 1][0][1]; else dp1[i][0][1] = 1; } } for (ll i = 1; i < n; i++) { for (ll j = 1; j < k; j++) { if (s[i] == '.' || s[i] == 'X') { ll cnt_ = get_(i, i + c[j] - 1); ll flag = 1; if (j == k - 1 && i + c[j] < n && getX(i + c[j], n - 1)) flag = 0; if (!(!flag || cnt_ || i + c[j] - 1 >= n)) { dp1[i][j][0] = dp1[i - 1][j][1]; } } if (s[i] == '.' || s[i] == '_') { dp1[i][j][1] = dp1[i - 1][j][1]; if (i - c[j - 1] < 0) continue; dp1[i][j][1] = add(dp1[i][j][1], dp1[i - c[j - 1]][j - 1][0]); } } } //----- for (ll i = n - 1; i >= 0; i--) { if (s[i] == '.' || s[i] == 'X') { ll cnt_ = get_(i, i + c[k - 1] - 1); ll cntX = (i + c[k - 1] >= n ? 0 : getX(i + c[k - 1], n - 1)); ll flag = 1; if (1 == c.size() && i && getX(0, i - 1)) flag = 0; if (!(!flag || cntX || cnt_ || i + c[k - 1] - 1 >= n)) { if (i + c[k - 1] < n) dp2[i][k - 1][0] = dp2[i + c[k - 1]][k - 1][1]; else dp2[i][k - 1][0] = 1; } } if (s[i] == '.' || s[i] == '_') { ll cntX = (i == n - 1 ? 0 : getX(i + 1, n - 1)); if (cntX) continue; if (i != n - 1) dp2[i][k - 1][1] = dp2[i + 1][k - 1][1]; else dp2[i][k - 1][1] = 1; } } for (ll i = n - 2; i >= 0; i--) { for (ll j = k - 2; j >= 0; j--) { if (s[i] == '.' || s[i] == 'X') { ll cnt_ = get_(i, i + c[j] - 1); ll flag = 1; if (!j && i && getX(0, i - 1)) flag = 0; if (!(!flag || cnt_ || i + c[j] - 1 >= n)) { if (i + c[j] < n) dp2[i][j][0] = dp2[i + c[j]][j][1]; } } if (s[i] == '.' || s[i] == '_') { dp2[i][j][1] = dp2[i + 1][j][1]; dp2[i][j][1] = add(dp2[i][j][1], dp2[i + 1][j + 1][0]); } } } for (ll i = 1; i < n; i++) { exl[i] = exl[i - 1]; if (i - c[k - 1] >= 0) exl[i] = add(exl[i], dp1[i - c[k - 1]][k - 1][0]); } for (ll i = n - 2; i >= 0; i--) { exr[i] = add(exr[i + 1], dp2[i + 1][0][0]); } // for (ll j = 0; j < k; j++) // { // for (ll i = 0; i < n; i++) // { // cout << dp1[i][j][1] << ' '; // } // cout << '\n'; // } // for (ll i = 0; i < n; i++) cout << exl[i] << ' '; // cout << "\n\n"; // for (ll i = 0; i < n; i++) cout << exr[i] << ' '; // cout << '\n'; // for (ll j = 0; j < k; j++) // { // for (ll i = 0; i < n; i++) // { // cout << dp2[i][j][1] << ' '; // } // cout << '\n'; // } // cout << '\n'; ll all = 0; for (ll i = 0; i < n; i++) { all = add(all, dp1[i][k - 1][0]); cnt[i] = add(cnt[i], mult(exl[i], dp2[i][k - 1][1])); for (ll j = 0; j < k; j++) { ll x = mult(dp1[i][j][0], dp2[i][j][0]); pref[i] = add(pref[i], x); if (i + c[j] < n) pref[i + c[j]] = sub(pref[i + c[j]], x); if (!j) x = mult(exr[i], dp1[i][j][1]); else x = mult(dp1[i][j][1], dp2[i][j - 1][1]); cnt[i] = add(cnt[i], x); } } // cout << all << endl; for (ll i = 1; i < n; i++) pref[i] = add(pref[i], pref[i - 1]); for (ll i = 0; i < n; i++) { // cout << cnt[i] << ' '; if (pref[i] == all) res.push_back('X'); else if (cnt[i] == all) res.push_back('_'); else res.push_back('?'); } // cout << '\n'; return res; }
#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...