Submission #900617

#TimeUsernameProblemLanguageResultExecution timeMemory
900617oviyan_gandhiSnake Escaping (JOI18_snake_escaping)C++17
100 / 100
1255 ms43384 KiB
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;

#define MAXN 20
int n, q;
string s;
int prv[1 << MAXN], dp[1 << MAXN], sub1[1 << MAXN];

int flip(int x){
    return ~x ^ ~((1 << n) - 1);
}

void sos(bool one){
    memset(dp, 0, sizeof(dp));
    for (int mask = 0; mask < (1 << n); mask++){
        dp[mask] = s[one ? mask : flip(mask)]-'0';
        if (mask & 1)
            dp[mask] += s[one ? (mask ^ 1) : flip(mask ^ 1)]-'0';
        prv[mask] = dp[mask];
    }
    for (int i = 1; i <= n; i++){
        for (int mask = 0; mask < (1 << n); mask++){
            dp[mask] = prv[mask];
            if (mask & (1 << i))
                dp[mask] += prv[mask ^ (1 << i)];
        }
        for (int mask = 0; mask < (1 << n); mask++)
            prv[mask] = dp[mask];
    }
    if (one)
        for (int mask = 0; mask < (1 << n); mask++)
            sub1[mask] = dp[mask];
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> q >> s;
    sos(1), sos(0);
    while (q--){
        string t; cin >> t;
        reverse(t.begin(), t.end());
        int cnt[]{0, 0, 0};
        for (char c : t){
            if (c == '?')
                cnt[0]++;
            else cnt[1+c-'0']++;
        }
        int least = min_element(cnt, cnt+3) - cnt - 1;
        int m = cnt[least+1], omask = 0;
        vector<int> pos;
        if (least == -1){
            for (int i = 0; i < n; i++){
                if (t[i] == '?')
                    pos.push_back(i);
                else if (t[i] == '1')
                    omask |= (1 << i);
            }
            int ans = 0;
            for (int i = 0; i < (1 << m); i++){
                int mask = omask;
                for (int j = 0; j < m; j++)
                    if (i & (1 << j))
                        mask |= (1 << pos[j]);
                ans += s[mask] - '0';
            }
            cout << ans << '\n';
            continue;
        }
        for (int i = 0; i < n; i++){
            if (t[i] == '?' || t[i] == ('0' + least))
                omask |= (1 << i);
            if (t[i] == ('0' + least))
                pos.push_back(i);
        }
        int *sub = (least ? sub1 : dp);
        int ans = 0;
        for (int i = 0; i < (1 << m); i++){
            int mask = omask;
            for (int j = 0; j < m; j++)
                if (i & (1 << j))
                    mask ^= (1 << pos[j]);
            if (__builtin_popcount(i) % 2) ans -= sub[mask];
            else ans += sub[mask];
        }
        cout << ans << '\n';
    }
    return 0;
}
#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...