Submission #567973

#TimeUsernameProblemLanguageResultExecution timeMemory
567973ngpin04Paint By Numbers (IOI16_paint)C++17
100 / 100
801 ms46476 KiB
    #include "paint.h"
    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define TASK ""
    #define bit(x) (1LL << (x))
    #define getbit(x, i) (((x) >> (i)) & 1)
    #define ALL(x) (x).begin(), (x).end() 
    using namespace std;
    template <typename T1, typename T2> bool mini(T1 &a, T2 b) {
        if (a > b) {a = b; return true;} return false;
    }
    template <typename T1, typename T2> bool maxi(T1 &a, T2 b) {
        if (a < b) {a = b; return true;} return false;
    }
    mt19937_64 rd(chrono::steady_clock::now().time_since_epoch().count());

    int rand(int l, int r) {
        return l + rd() % (r - l + 1);
    }
    const int N = 2e5 + 5; 
    const int K = 105;
    const int oo = 1e9;
    const long long ooo = 1e18;
    const int mod = 1e9 + 7; // 998244353;
    const long double pi = acos(-1);

    int cnt[N][2];
    int ans[N][2];
    int a[N];
    int b[N];
    int n,k;

    bool pre[N][K];
    bool suf[N][K];

    int fix(char c) {
        if (c == '.')
            return -1;
        if (c == '_')
            return 0;
        return 1;
    }

    int check(int l, int r, int v) {
        return (cnt[r][v] - cnt[l - 1][v]) > 0;
    }

    void solve() {

        for (int i = 1; i <= n; i++) {
            if (a[i] != -1)
                cnt[i][a[i]]++;
            for (int j = 0; j < 2; j++)
                cnt[i][j] += cnt[i - 1][j];
        }

        for (int i = 0; i <= n; i++) {
            if (a[i] == 1)
                break;
            pre[i][0] = 1;
        }

        for (int j = 1; j <= k; j++)
        for (int i = b[j]; i <= n; i++) {
            if (a[i] != 1)
                pre[i][j] |= pre[i - 1][j];
            if (!check(i - b[j] + 1, i, 0)) {
                int it = i - b[j];
                if (a[it] != 1)
                    pre[i][j] |= pre[max(0, it - 1)][j - 1];
            }
        }

        for (int i = n + 1; i >= 1; i--) {
            if (a[i] == 1)
                break;
            suf[i][k + 1] = 1;
        }

        for (int j = k; j >= 1; j--)
        for (int i = n - b[j] + 1; i >= 1; i--) {
            if (a[i] != 1)
                suf[i][j] |= suf[i + 1][j];
            if (!check(i, i + b[j] - 1, 0)) {
                int it = i + b[j];
                if (a[it] != 1)
                    suf[i][j] |= suf[min(n + 1, it + 1)][j + 1];
            }
        }

        for (int i = 1; i <= n; i++) if (a[i] != 1) 
        for (int j = 0; j <= k; j++)
            if (pre[i - 1][j] && suf[i + 1][j + 1])
                ans[i][0] = true;

        for (int j = 1; j <= k; j++) 
        for (int l = 1, r = b[j]; r <= n; l++, r++) if (!check(l, r, 0)) {
            if (j > 1 && a[l - 1] == 1)
                continue;
            if (j < k && a[r + 1] == 1)
                continue;
            int u = (l - 1) - (j > 1);
            int v = (r + 1) + (j < k);
            if (u < 0 || v > n + 1)
                continue;
            if (pre[u][j - 1] && suf[v][j + 1]) {
                ans[l][1]++;
                ans[r + 1][1]--;
                // cerr << l << " " << r << " " << j << "\n";
            }
        }

        for (int i = 1; i <= n; i++)
            ans[i][1] += ans[i - 1][1];
    }

    string solve_puzzle(string s, vector<int> c) {
        n = s.size();
        k = c.size();
        for (int i = 1; i <= n; i++)
            a[i] = fix(s[i - 1]);

        for (int i = 1; i <= k; i++)
            b[i] = c[i - 1];

        solve();

        string res;
        for (int i = 1; i <= n; i++) {
            // assert(ans[i][0] || ans[i][1]);
            if (ans[i][0] && ans[i][1])
                res += '?';
            else if (ans[i][0])
                res += '_';
            else
                res += 'X';
        }
        return res;
    }

    //#include "grader.cpp"
#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...