제출 #59744

#제출 시각아이디문제언어결과실행 시간메모리
59744model_codeparentrises (BOI18_parentrises)C++17
100 / 100
276 ms15348 KiB
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

const string IMPOSSIBLE = "impossible";
const int MOD = (int) 1e9 + 7;

enum Color {
    GREEN = 'G',
    RED = 'R',
    BLUE = 'B',
};

template<class F>
string filter(const string& s, const F& pred) {
    string ret;
    for (int i = 0; i < (int) s.length(); ++i) {
        if (pred(i, s[i])) {
            ret += s[i];
        }
    }
    return ret;
}

bool check(string s) {
    int balance = 0;
    for (char c: s) {
        if (c == '(') {
            balance++;
        } else {
            balance--;
            if (balance < 0) {
                return false;
            }
        }
    }
    return balance == 0;
}

string reconstruct(string s) {
    int n = (int) s.length();
    vector<Color> color(n, Color::GREEN);
    vector<int> greenOpen, greenClosed;
    int balance = 0;
    for (int i = 0; i < n; ++i) {
        if (s[i] == '(') {
            greenOpen.push_back(i);
            balance++;
        } else {
            balance--;
            greenClosed.push_back(i);
            if (balance < 0) {
                balance = 0;
                if (greenClosed.size() < 2U) {
                    return IMPOSSIBLE;
                }
                int pos1 = greenClosed.back();
                greenClosed.pop_back();
                int pos2 = greenClosed.back();
                greenClosed.pop_back();
                color[pos1] = Color::RED;
                color[pos2] = Color::BLUE;
            }
        }
    }
    while (balance-- > 0) {
        if (greenOpen.size() < 2U) {
            return IMPOSSIBLE;
        }
        int pos1 = greenOpen.back();
        greenOpen.pop_back();
        int pos2 = greenOpen.back();
        greenOpen.pop_back();
        color[pos1] = Color::RED;
        color[pos2] = Color::BLUE;
    }
    string s1 = filter(s, [&color](int index, char c) -> bool {
        return color[index] == Color::RED || color[index] == Color::GREEN;
    });
    string s2 = filter(s, [&color](int index, char c) -> bool {
        return color[index] == Color::BLUE || color[index] == Color::GREEN;
    });
    string ans;
    for (int i = 0; i < n; ++i) {
        ans += (char) color[i];
    }
    return (check(s1) && check(s2)) ? ans: IMPOSSIBLE;
}

vector<int> count(int n) {
    vector<vector<int>> dp(n + 5, vector<int>(2 * n + 5, 0));
    auto ndp = dp;
    vector<int> ans(n + 1);
    ans[0] = 1;
    dp[0][0] = 1;
    for (int i = 1; i <= n; ++i) {
        for (auto& v: ndp) {
            fill(v.begin(), v.end(), 0);
        }
        for (int left = 0; left <= n; ++left) {
            for (int right = left; right <= 2 * i; ++right) {
                ndp[left + 1][right + 2] += dp[left][right];
                ndp[left + 1][right + 2] %= MOD;
                int nLeft = max(0, left - 2);
                int nRight = right - 1;
                if (nLeft <= nRight) {
                    ndp[nLeft][nRight] += dp[left][right];
                    ndp[nLeft][nRight] %= MOD;
                }
            }
        }
        ndp.swap(dp);
        ans[i] = 0;
        for (int right = 0; right <= 2 * i; ++right) {
            ans[i] += dp[0][right];
            ans[i] %= MOD;
        }
    }
    return ans;
}

int main() {
    int type;
    cin >> type;

    if (type == 1) {
        int T;
        cin >> T;

        while (T-- > 0) {
            string s;
            cin >> s;
            cout << reconstruct(move(s)) << '\n';
        }
    } else {
        int T;
        cin >> T;

        vector<int> qs(T);
        for (int& x: qs) {
            cin >> x;
        }
        vector<int> ans = count(*max_element(qs.begin(), qs.end()));
        for (int x: qs) {
            cout << ans[x] << '\n';
        }
    }
}
#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...