Submission #1327839

#TimeUsernameProblemLanguageResultExecution timeMemory
1327839shirokuma5Homework (CEOI22_homework)C++20
23 / 100
376 ms359488 KiB
#include<bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
using B = bitset<16>;

string s;
vector<int> quest, kakko, minMax, cnt;
void print(const vector<int> &a) {
    for (int x : a) cerr << " " << x;
    cerr << endl;
}

vector<vector<int>> G;
vector<vector<B>> dp;
int cur = 0, n = 0;

// [l, r) の木を構築
void calc(int now, int l = 0, int r = s.size()) {
    int left = 0, right = 0;
    if (s[l+1] == 'i') minMax[now] = 0;
    else minMax[now] = 1;
    // 辺の構築
    if (s[l+4] == '?') {
        cnt[now]++;
        G[now].push_back(quest[l+4]);
    }
    else {
        G[now].push_back(cur++); calc(cur-1, l+4, kakko[l+7]+1); cnt[now] += cnt[G[now][0]];
    }
    if (s[r-2] == '?') {
        G[now].push_back(quest[r-2]); cnt[now]++;
    }
    else {
        G[now].push_back(cur++); calc(cur-1, kakko[r-2]-3, r-1); cnt[now] += cnt[G[now][1]];
    }
}
// dfsでとる値の計算
void dfs(int now, int bit) {
    if (dp[now][bit].any()) return;
    if (now < n) {
        B bs(bit);
        if (bs.count() == 1) dp[now][bit] = bs;
        //cerr << "dfs " << now << " " << bit << " " << bs << endl;
        return;
    }
    for (int sub = bit; sub >= 0; sub--) {
        sub &= bit;
        if (B(sub).count() != cnt[G[now][0]]) continue;
        dfs(G[now][0], sub); dfs(G[now][1], bit^sub);
        if (dp[G[now][0]][sub].none() || dp[G[now][1]][bit ^ sub].none()) continue;
        B bs(0);
        if (minMax[now] == 1) {
            bool pl = 0, pr = 0;
            rep(i, 16) {
                if (dp[G[now][0]][sub].test(i)) {
                    if (pr) bs.set(i);
                    pl = 1;
                }
                if (dp[G[now][1]][bit^sub].test(i)) {
                    if (pl) bs.set(i);
                    pr = 1;
                }
            }
        }
        else {
            bool pl = 0, pr = 0;
            for (int i = 15; i >= 0; i--) {
                if (dp[G[now][0]][sub].test(i)) {
                    if (pr) bs.set(i);
                    pl = 1;
                }
                if (dp[G[now][1]][bit^sub].test(i)) {
                    if (pl) bs.set(i);
                    pr = 1;
                }
            }
        }
        dp[now][bit] |= bs;
    }
    //cerr << "dfs " << now << " " << bit << " " << dp[now][bit] << endl;
}

int main() {
    cin >> s;
    if (s == "?") {
        cout << 1 << endl; return 0;
    }
    quest.assign(s.size(), -1); kakko.assign(s.size(), -1);
    stack<int> st;
    rep(i, s.size()) {
        if (s[i] == '?') {
            quest[i] = n; n++;
        }
        else if (s[i] == '(') st.push(i);
        else if (s[i] == ')') {
            kakko[i] = st.top(); kakko[st.top()] = i; st.pop();
        }
    }
    minMax.resize(n * 2 + 3, -1); G.resize(n * 2 + 3); cur = n + 1; // min 0 max 1
    cnt.resize(n * 2 + 3, 0);
    calc(n);
    for (int i = 0; i < n; i++) cnt[i] = 1;

    dp.assign(n * 2 + 3, vector<B> (1<<n, B(0)));
    dfs(n, (1<<n)-1);
    cout << dp[n][(1<<n)-1].count() << endl;
}
#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...