제출 #886848

#제출 시각아이디문제언어결과실행 시간메모리
886848sochoSnake Escaping (JOI18_snake_escaping)C++14
100 / 100
1025 ms43284 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double D;
typedef vector<int> VI;
typedef set<int> SI;
typedef map<int, int> MII;
typedef pair<int, int> PII;

#define A first
#define B second
#define SZ(x) int(x.size())
#define PB push_back
#define FR(i, a, b) for (int i = (a); i < (b); i++)
#define FOR(i, n) FR(i, 0, n)
#define RF(i, a, b) for (int i = (a); i >= (b); i--)
#define FRA(a, x) for (auto a: (x))

template <typename T> inline void set_min(T &a, T b) {if(b < a) a = b;}
template <typename T> inline void set_max(T &a, T b) {if(b > a) a = b;}

int n, q;
string se;
const int MXN = 20;
int dp[1<<MXN];
int dp2[1<<MXN];
int val[1<<MXN];

int ms[MXN];
int p;

signed main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	
	cin >> n >> q;
	cin >> se;
	
	FOR(i, 1<<n) {
		val[i] = (se[i] - '0');
		dp[i] = dp2[i] = (se[i] - '0');
	}
	
	FOR(b, n) {
		FOR(i, 1<<n) {
			if (i & (1 << b)) dp[i] += dp[i ^ (1 << b)];
			else dp2[i] += dp2[i ^ (1 << b)];
		}
	}
	
	string s;
	FOR(_, q) {
		cin >> s;
		reverse(s.begin(), s.end());
		
		int n0 = 0, n1 = 0, nq = 0;
		FRA(x, s) {
			if (x == '?') nq++;
			else if (x == '0') n0++;
			else n1++;
		}
		
		int ans = 0;
		if (nq <= 6) {
			// just add over the bitmasks
			int main = 0;
			FOR(i, n) {
				if (s[i] == '?') ms[p++] = i;
				else if (s[i] == '1') main += (1 << i);
			}
			FOR(i, 1<<nq) {
				int p = main;
				FOR(j, nq) {
					if (i & (1 << j)) p += (1 << ms[j]);
				}
				ans += val[p];
			}
		}
		else if (n0 <= 6) {
			// 0011??
			// super(001100)
			// -super(011100)
			// -super(101100)
			// +super(111100)
			int main = 0;
			FOR(i, n) {
				if (s[i] == '0') ms[p++] = i;
				else if (s[i] == '1') main += (1 << i);
			}
			FOR(i, 1<<n0) {
				int p = main;
				FOR(j, n0) {
					if (i & (1 << j)) {
						p += (1 << ms[j]);
					}
				}
				if (__builtin_popcount(i) % 2 == 0) ans += dp2[p];
				else ans -= dp2[p];
			}
		}
		else { // n1 <= 6
			// 0011??
			// sub(001111)
			// -sub(001011)
			// -sub(000111)
			// +sub(000011)
			int main = 0;
			FOR(i, n) {
				if (s[i] == '1') ms[p++] = i;
				else if (s[i] == '?') main += (1 << i);
			}
			FOR(i, 1<<n1) {
				int p = main;
				FOR(j, n1) {
					if (i & (1 << j)) p += (1 << ms[j]);
				}
				if ((n1 - __builtin_popcount(i)) % 2 == 0) ans += dp[p];
				else ans -= dp[p];
			}
		}
		cout << ans << '\n';
		p = 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...