Problem:
毒蛇の脱走(Snake Escaping)
JOI 研究所では
2^L
匹の毒蛇を飼っており，それぞれ
0, 1, ..., 2^L - 1
の番号が付けられている．すべての毒蛇は頭から順に
L
個の部分に分かれており，それぞれの部分は青または赤である．毒蛇
i
に対し，
i
を2進表記して
i =
$\sum_{k=1}^{L}$
c_k2^{L-k} (0 \leq c_k \leq 1)
とおいたとき，
c_k = 0
であれば，毒蛇
i
の頭から数えて
k
番目の部分は青であり，
c_k = 1
であれば，毒蛇
i
の頭から数えて
k
番目の部分は赤である．
各毒蛇には毒性と呼ばれる0 以上9 以下の整数値が定まっている．
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
からなる長さ
2^L
の文字列
S
が与えられ，その
i
文字目(
1 \leq i \leq 2^L
) は毒蛇
i - 1
の毒性を表す．
毒蛇たちの動きは素早いので，JOI 研究所からは，よく毒蛇たちが脱走してしまう．JOI 研究所には脱走した毒蛇を目撃した周辺住民から苦情が寄せられる．
あなたには，
Q
日間にわたる苦情の情報が与えられる．
d
日目(
1 \leq d \leq Q
) に寄せられた苦情は，
0
,
1
,
?
からなる長さ
L
の文字列
T_d
として表され，
T_d
の
j
文字目(
1 \leq j \leq L
) が
0
の場合は，
d
日目に脱走したすべての毒蛇の頭から数えて
j
番目の部分が青であることを表し，
T_d
の
j
文字目(
1 \leq j \leq L
) が
1
の場合は，
d
日目に脱走したすべての毒蛇の頭から数えて
j
番目の部分が赤であることを表し，
T_d
の
j
文字目(
1 \leq j \leq L
) が
?
の場合は，
d
日目に脱走した毒蛇の頭から数えて
j
番目の部分については，周辺住民からは情報が与えられなかったことを表す．
苦情はすべて正確な情報である．脱走した毒蛇はJOI 研究所の職員がその日のうちに捕獲する．捕獲された毒蛇が，翌日以降に再び脱走することはあり得る．
毒蛇の脱走によるリスクを見積もるために，JOI 研究所のK 理事長は脱走した可能性のある毒蛇の毒性の合計を知りたい．あなたの仕事は，
Q
日間にわたる苦情の情報から，それぞれの日ごとに，その日に脱走した可能性のある毒蛇の毒性の合計を求めるプログラムを作成することである．
課題
毒蛇の毒性を表す文字列
S
と，
Q
日間の苦情の情報が与えられるので，それぞれの日ごとに，その日に脱走した可能性のある毒蛇の毒性の合計を求めるプログラムを作成せよ．
メモリ制限が小さいことに注意すること．
入力
標準入力から以下の入力を読み込め．
1 行目には，整数
L, Q
が空白を区切りとして書かれている．これらは順に，毒蛇の部分の個数と，苦情の寄せられる日数を表す．
2 行目には，長さ
2^L
の文字列
S
が書かれている．この文字列は毒蛇の毒性を表す．
続く
Q
行のうちの
d
行目(
1 \leq d \leq Q
) には，長さ
L
の文字列
T_d
が書かれている．この文字列は
d
日目の苦情を表す．
出力
標準出力に
Q
行で出力せよ．
d
行目には，
d
日目に脱走した可能性のある毒蛇の毒性の合計を表す整数を出力せよ．
制限
すべての入力データは以下の条件を満たす．
1 \leq L \leq 20
．
1 \leq Q \leq 1 000 000
．
S
は長さ
2^L
の文字列である．
文字列
S
は
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
からなる．
T_d
は長さ
L
の文字列である(
1 \leq d \leq Q
)．
文字列
T_d
は
0
,
1
,
?
からなる(
1 \leq d \leq Q
)．
入出力例
入力例1
3 5
12345678
000
0??
1?0
?11
???
出力例1
1
10
12
12
36
この入力例では，
L = 3
である．3 つの部分に分かれた毒蛇が，全部で
2^3 = 8
匹いる．苦情は5 日間にわたって寄せられる．
1 日目に脱走した可能性のある毒蛇は，毒蛇0 のみである．毒性の合計は1 である．
2 日目に脱走した可能性のある毒蛇は，毒蛇0, 1, 2, 3 である．毒性の合計は10 である．
3 日目に脱走した可能性のある毒蛇は，毒蛇4, 6 である．毒性の合計は12 である．
4 日目に脱走した可能性のある毒蛇は，毒蛇3, 7 である．毒性の合計は12 である．
5 日目に脱走した可能性のある毒蛇は，毒蛇0, 1, 2, 3, 4, 5, 6, 7 である．毒性の合計は36 である．
入力例2
4 8
3141592653589793
0101
?01?
??1?
?0??
1?00
01?1
??10
????
出力例2
9
18
38
30
14
15
20
80
情報オリンピック日本委員会作 『第17 回日本情報オリンピック(JOI 2017/2018) 本選』

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

int l, q;
int n[1 << 20], m[1 << 20], a, b, c, x[21], y[21], z[21], ans, p;
char s[(1 << 20) + 1], t[21];

int main() {
    // 入力の受け取り
    scanf("%d%d %s", &l, &q, s);
    
    // 初期化
    for (int i = 0; i < (1 << l); i++) {
        n[i] = s[i] - '0';
        m[i] = s[i] - '0';
    }
    
    // 前計算: nとmを更新
    for (int i = 0; i < l; i++) {
        for (int k = 0; k < (1 << l); k++) {
            if ((k & (1 << i)) == 0) {
                n[k] += n[k | (1 << i)];
            } else {
                m[k] += m[k ^ (1 << i)];
            }
        }
    }
    
    // クエリ処理
    while (q--) {
        scanf(" %s", t);
        a = b = c = ans = p = 0;
        
        // 入力されたビット文字列を解析
        for (int i = 0; i < l; i++) {
            if (t[l - i - 1] == '0') {
                x[a++] = i;
            } else if (t[l - i - 1] == '1') {
                y[b++] = i;
                p += (1 << i);
            } else {
                z[c++] = i;
            }
        }
        
        // aの要素が6以下の場合の処理
        if (a <= 6) {
            for (int i = 0; i < (1 << a); i++) {
                int o = p, w = 0;
                for (int j = 0; j < a; j++) {
                    if (i >> j & 1) {
                        o += (1 << x[j]);
                        w++;
                    }
                }
                if (w % 2) ans -= n[o];
                else ans += n[o];
            }
        } 
        // bの要素が6以下の場合の処理
        else if (b <= 6) {
            for (int i = 0; i < c; i++) p += (1 << z[i]);
            for (int i = 0; i < (1 << b); i++) {
                int o = p, w = 0;
                for (int j = 0; j < b; j++) {
                    if (i >> j & 1) {
                        o -= (1 << y[j]);
                        w++;
                    }
                }
                if (w % 2) ans -= m[o];
                else ans += m[o];
            }
        } 
        // それ以外の場合の処理
        else {
            for (int i = 0; i < (1 << c); i++) {
                int o = p;
                for (int j = 0; j < c; j++) if (i >> j & 1) o += (1 << z[j]);
                ans += (s[o] - '0');
            }
        }
        
        // 結果を出力
        printf("%d\n", ans);
    }
    return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 12788
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <cstring>
using namespace std;

int main() {
    int l, q;
    cin >> l >> q;
    string s;
    cin >> s;

    vector<int> n(1 << l), m(1 << l);
    for (int i = 0; i < (1 << l); ++i) {
        n[i] = s[i] - '0';
        m[i] = s[i] - '0';
    }

    for (int i = 0; i < l; ++i) {
        for (int k = 0; k < (1 << l); ++k) {
            if ((k & (1 << i)) == 0) n[k] += n[k | (1 << i)];
            else m[k] += m[k ^ (1 << i)];
        }
    }

    while (q--) {
        string t;
        cin >> t;

        vector<int> x, y, z;
        int a = 0, b = 0, c = 0, ans = 0, p = 0;

        for (int i = 0; i < l; ++i) {
            if (t[l - i - 1] == '0') x.push_back(i);
            else if (t[l - i - 1] == '1') {
                y.push_back(i);
                p += (1 << i);
            } else z.push_back(i);
        }

        if (x.size() <= 6) {
            for (int i = 0; i < (1 << x.size()); ++i) {
                int o = p, w = 0;
                for (int j = 0; j < x.size(); ++j) {
                    if (i >> j & 1) {
                        o += (1 << x[j]);
                        w++;
                    }
                }
                if (w % 2) ans -= n[o];
                else ans += n[o];
            }
        } else if (y.size() <= 6) {
            for (int i = 0; i < z.size(); ++i) p += (1 << z[i]);
            for (int i = 0; i < (1 << y.size()); ++i) {
                int o = p, w = 0;
                for (int j = 0; j < y.size(); ++j) {
                    if (i >> j & 1) {
                        o -= (1 << y[j]);
                        w++;
                    }
                }
                if (w % 2) ans -= m[o];
                else ans += m[o];
            }
        } else {
            for (int i = 0; i < (1 << z.size()); ++i) {
                int o = p;
                for (int j = 0; j < z.size(); ++j) if (i >> j & 1) o += (1 << z[j]);
                ans += (s[o] - '0');
            }
        }
        cout << ans << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 1760
memory_kb: 13144
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cmath>

int main() {
    int l, q;
    std::cin >> l >> q;
    
    std::string s;
    std::cin >> s;

    std::vector<int> n(1 << l), m(1 << l);
    for (int i = 0; i < (1 << l); ++i) {
        n[i] = s[i] - '0';
        m[i] = s[i] - '0';
    }

    for (int i = 0; i < l; ++i) {
        for (int k = 0; k < (1 << l); ++k) {
            if ((k & (1 << i)) == 0) {
                n[k] += n[k | (1 << i)];
            } else {
                m[k] += m[k ^ (1 << i)];
            }
        }
    }

    while (q--) {
        std::string t;
        std::cin >> t;

        int a = 0, b = 0, c = 0, ans = 0, p = 0;
        std::vector<int> x(21), y(21), z(21);

        for (int i = 0; i < l; ++i) {
            if (t[l - i - 1] == '0') {
                x[a++] = i;
            } else if (t[l - i - 1] == '1') {
                y[b++] = i;
                p += (1 << i);
            } else {
                z[c++] = i;
            }
        }

        if (a <= 6) {
            for (int i = 0; i < (1 << a); ++i) {
                int o = p, w = 0;
                for (int j = 0; j < a; ++j) {
                    if (i >> j & 1) {
                        o += (1 << x[j]);
                        w++;
                    }
                }
                if (w % 2) ans -= n[o];
                else ans += n[o];
            }
        } else if (b <= 6) {
            for (int i = 0; i < c; ++i) p += (1 << z[i]);
            for (int i = 0; i < (1 << b); ++i) {
                int o = p, w = 0;
                for (int j = 0; j < b; ++j) {
                    if (i >> j & 1) {
                        o -= (1 << y[j]);
                        w++;
                    }
                }
                if (w % 2) ans -= m[o];
                else ans += m[o];
            }
        } else {
            for (int i = 0; i < (1 << c); ++i) {
                int o = p;
                for (int j = 0; j < c; ++j) {
                    if (i >> j & 1) o += (1 << z[j]);
                }
                ans += (s[o] - '0');
            }
        }

        std::cout << ans << std::endl;
    }

    return 0;
}
accuracy: 1
time_ms: 1510
memory_kb: 12500
final_rank: 6

code_snippet: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>

#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <limits>
#include <numeric>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

struct IO_Tp {
    const static int _O_Buffer_Size = 10 << 20;
    char _O_Buffer[_O_Buffer_Size], *_O_pos = _O_Buffer;

    IO_Tp() {}

    ~IO_Tp() { fwrite(_O_Buffer, 1, _O_pos - _O_Buffer, stdout); }

    IO_Tp &operator<<(int n) {
        static char _buf[10];
        char *_pos = _buf;
        do
            *_pos++ = '0' + n % 10;
        while (n /= 10);
        while (_pos != _buf) *_O_pos++ = *--_pos;
        return *this;
    }

    IO_Tp &operator<<(char ch) {
        *_O_pos++ = ch;
        return *this;
    }
} IO;

const int N = 1000010, L = 20;

int l, n;
char v[(1 << L) + 10];
char tmp[L + 4];
unsigned short sum[1 << 12][1 << 12];
int ind[N], cc[N];
int ans[N];

int main() {

    scanf("%d%d%s", &l, &n, v);
    for (int i = 1; i <= n; ++i) {
        scanf("%s", tmp + 1);
        for (int j = 0; j < l; ++j)
            if (tmp[l - j] == '?')
                cc[i] |= 1 << j;
            else
                ind[i] |= (tmp[l - j] - '0') << j;
    }
    int a = max(0, l - int(log(n) / log(3))), b = l - a;
    if (a > 12) {
        a = 12;
        b = l - a;
    } else if (b > 12) {
        b = 12;
        a = l - b;
    }
    for (int i = 0; i != (1 << l); ++i) v[i] -= '0';
    for (int pre = 0; pre != 1 << a; ++pre) {
        for (int s = 0; s != 1 << b; ++s) sum[0][s] = v[pre | s << a];
        for (int cov = 1; cov != 1 << b; ++cov) {
            int tr = __builtin_ctz(cov);
            int ccov = ~cov & ((1 << b) - 1);
            for (int s = ccov;; s = (s - 1) & ccov) {
                sum[cov][s] = sum[cov ^ 1 << tr][s] + sum[cov ^ 1 << tr][s | 1 << tr];
                if (!s)
                    break;
            }
        }

        for (int i = 1; i <= n; ++i)
            if ((~cc[i] & pre) == (ind[i] & ((1 << a) - 1)))
                ans[i] += sum[cc[i] >> a][ind[i] >> a];

        for (int cov = 0; cov != 1 << b; ++cov)
            for (int s = cov;; s = (s - 1) & cov) {
                sum[~cov & ((1 << b) - 1)][s & cov] = 0;
                if (!s)
                    break;
            }
    }

    for (int i = 1; i <= n; ++i) IO << ans[i] << '\n';

    return 0;
}
accuracy: 1
time_ms: 1750
memory_kb: 52812
final_rank: 10

code_snippet: #include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<math.h>
#include<string>
#include<stdio.h>
#pragma GCC optimize ("O3")
using namespace std;
#define vel vector<int>
#define vvel vector<vel>
#define sor(a) sort(a.begin(),a.end())
#define rep(i,n) for(int i=0;i<n;i++)
#define upperbound(v,val) upper_bound(v.begin(),v.end(),val)
#define lowerbound(v,val) lower_bound(v.begin(),v.end(),val)
int rui[21];
int ord[(1 << 20) + 1];
void make_ord() {
	ord[1] = 0;
	int max1 = 0;
	for (int i = 2; i <= (1 << 20); i++) {
		int mi = (i&(-i));
		if (i == mi) {
			max1++;
			ord[i] = max1;
		}
		else { ord[i] = ord[mi]; }
	}
}
signed main() {
	make_ord();
	int L; cin >> L; int q; cin >> q;
	vvel lis(3, vel(1 << L));
	string s; cin >> s;
	int sz = 1 << L;
	rep(i, sz) { lis[0][i] = s[i] - '0'; }
	lis[1] = lis[0];
	lis[2] = lis[0];
	rep(i, L) {
		rep(j, sz) {
			int smt = (j >> i);
			int pla = 2-(smt%2);
			lis[pla][j] += lis[pla][j xor (1<<i)];
		}
	}
	int pot = 0;
	rep(i, sz) {
		if (i % 2 == 1) { lis[1][pot] *= -1; lis[2][pot] *= -1; }
		pot ^=1<<ord[i];
	}
	int all[3][20];
	bool fl = (q <= 50000);
	rep(i, q) {
		string s; cin >> s;
		int c[3]; c[0] = 0; c[1] = 0; c[2] = 0;
		int num = 0;
		for (int j = L - 1; j >= 0; j--) {
			int pla = (s[L - 1 - j] + 1) % 16;
			all[pla][c[pla]] = j;
			c[pla]++;
			if (pla == 2) { num += (1 << j); }
		}
		int ans0 = 0;
		if (fl) {
			if (c[0] <= min(c[1], c[2])) {
				int lim = (1 << c[0]) - 1;
				rep(j, lim) {
					ans0 += lis[0][num];
					num ^= 1 << all[0][ord[j + 1]];
				}
				ans0 += lis[0][num];
			}
			else if (c[1] < c[2]) {
				int lim = (1 << c[1]) - 1;
				rep(j, lim) {
					ans0 += lis[2][num];
					num ^= 1 << all[1][ord[j + 1]];
				}
				ans0 += lis[2][num];
			}
			else {
				rep(j, c[0]) { num += (1 << all[0][j]); }
				int lim = (1 << c[2]) - 1;
				rep(j, lim) {
					ans0 += lis[1][num];
					num ^= 1 << all[2][ord[j + 1]];
				}
				ans0 += lis[1][num];
			}
			printf("%d\n", abs(ans0));
		}
	}
	return 0;
}
accuracy: 0.11764705882352941
time_ms: 530
memory_kb: 7400
final_rank: 11

code_snippet: #include <iostream>
#include <string>
#include <vector>
using namespace std;
#pragma warning (disable: 4996)

long long L, Q, A[1 << 20], dp0[1 << 20], dp1[1 << 20];

void init() {
	for (int i = 0; i < (1 << L); i++) { dp0[i] = A[i]; dp1[(1 << L) - i - 1LL] = A[i]; }

	for (int i = 0; i < L; i++) {
		for (int j = 0; j < (1 << L); j++) {
			if ((j&(1 << i)) != 0) { dp0[j] += dp0[j - (1 << i)]; }
		}
	}
	for (int i = 0; i < L; i++) {
		for (int j = 0; j < (1 << L); j++) {
			if ((j&(1 << i)) != 0) { dp1[j] += dp1[j - (1 << i)]; }
		}
	}
}

int A1[1 << 20], A2[1 << 20], cnts;

void enumerate(vector<int>I) {
	cnts = 0; int N = I.size();

	int sum = 0, cnt = 0;
	for (int i = 0; i < (1 << I.size()); i++) {
		A1[cnts] = sum; A2[cnts] = ((N - cnt) & 1); cnts++;

		int cx = i, ss = 0;
		while ((cx & 1) == 1) {
			cx >>= 1; sum -= (1 << I[ss]); ss++; cnt--;
		}
		if (ss < N) { sum += (1 << I[ss]); cnt++; }
	}
}

int main() {
	cin >> L >> Q;
	for (int i = 0; i < (1 << L); i++) { char c; cin >> c; A[i] = (c - '0'); }

	init();

	for (int i = 1; i <= Q; i++) {
		char c[22]; scanf("%s", c);
		for (int j = 0; j < L; j++) { if (j < (L - 1 - j)) swap(c[j], c[L - 1 - j]); }
		
		vector<int>v0, v1, v2;
		for (int j = 0; j < L; j++) {
			if (c[j] == '0') v0.push_back(j);
			if (c[j] == '1') v1.push_back(j);
			if (c[j] == '?') v2.push_back(j);
		}

		int ans = 0;
		if (v2.size() <= 7) {
			enumerate(v2);
			int BASE = 0; for (int j = 0; j < v1.size(); j++) BASE += (1 << v1[j]);
			for (int j = 0; j < cnts; j++) {
				ans += A[BASE + A1[j]];
			}
		}
		else if (v0.size() <= v1.size()) {
			enumerate(v0);
			int BASE = 0; for (int j = 0; j < v2.size(); j++) BASE += (1 << v2[j]);

			for (int j = 0; j < cnts; j++) {
				if (A2[j] == 0) ans += dp1[BASE + A1[j]];
				if (A2[j] == 1) ans -= dp1[BASE + A1[j]];
			}
		}
		else {
			enumerate(v1);
			int BASE = 0; for (int j = 0; j < v2.size(); j++) BASE += (1 << v2[j]);

			for (int j = 0; j < cnts; j++) {
				if (A2[j] == 0) ans += dp0[BASE + A1[j]];
				if (A2[j] == 1) ans -= dp0[BASE + A1[j]];
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 1390
memory_kb: 27864
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
int l,q,n[1<<20],m[1<<20],a,b,c,x[21],y[21],z[21],ans,p;
char s[(1<<20)+1],t[21];
int main(void){
    scanf("%d%d %s",&l,&q,s);
    for(int i=0;i<1<<l;i++){
        n[i]=s[i]-'0';
        m[i]=s[i]-'0';
    }
    for(int i=0;i<l;i++){
        for(int k=0;k<1<<l;k++){
            if((k&(1<<i))==0)n[k]+=n[k|(1<<i)];
            else m[k]+=m[k^(1<<i)];
        }
    }
    while(q--){
        scanf(" %s",t);
        a=0,b=0,c=0,ans=0,p=0;
        for(int i=0;i<l;i++){
            if(t[l-i-1]=='0')x[a++]=i;
            else if(t[l-i-1]=='1'){
                y[b++]=i;
                p+=(1<<i);
            }else z[c++]=i;
        }
        if(a<=6){
            for(int i=0;i<1<<a;i++){
                int o=p,w=0;
                for(int j=0;j<a;j++){
                    if(i>>j&1){
                        o+=(1<<x[j]);
                        w++;
                    }
                }
                if(w%2)ans-=n[o];
                else ans+=n[o];
            }
        }else if(b<=6){
            for(int i=0;i<c;i++)p+=(1<<z[i]);
            for(int i=0;i<1<<b;i++){
                int o=p,w=0;
                for(int j=0;j<b;j++){
                    if(i>>j&1){
                        o-=(1<<y[j]);
                        w++;
                    }
                }
                if(w%2)ans-=m[o];
                else ans+=m[o];
            }
        }else{
            for(int i=0;i<1<<c;i++){
                int o=p;
                for(int j=0;j<c;j++)if(i>>j&1)o+=(1<<z[j]);
                ans+=(s[o]-'0');
            }
        }
        printf("%d\n",ans);
    }
}
accuracy: 1
time_ms: 730
memory_kb: 12452
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

//#define FILE_IO

int N, Q, ans;
int i, j, q, msk;
int cnt[3];
int val[1100005], dp[1100005], dp2[1100005];
int bts[1100005];
int B, b[25];
char s[1100005];

void bck0(int pas, int msk, int smn)
{
    if(pas >= B)
    {
        ans += smn * dp[msk];
        return;
    }

    bck0(pas + 1, msk, smn);
    bck0(pas + 1, msk ^ (1 << b[pas]), -smn);
}

void bck1(int pas, int msk, int smn)
{
    if(pas >= B)
    {
        ans += smn * dp2[msk];
        return;
    }

    bck1(pas + 1, msk, smn);
    bck1(pas + 1, msk ^ (1 << b[pas]), -smn);
}

void bckq(int pas, int msk)
{
    if(pas >= B)
    {
        ans += val[msk];
        return;
    }

    bckq(pas + 1, msk);
    bckq(pas + 1, msk ^ (1 << b[pas]));
}

int main()
{
    #ifdef FILE_IO
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
    #endif

    scanf("%d%d\n", &N, &Q);
    scanf("%s\n", s);
    for(i = 0; i < (1 << N); i++)
        val[i] = dp[i] = dp2[i] = s[i] - '0';
    for(j = 0; j < N; j++)
        for(i = (1 << N) - 1; i >= 0; i--)
            if( (i & (1 << j)) == 0 )
                dp[i] += dp[i ^ (1 << j)];
    for(j = 0; j < N; j++)
        for(i = 0; i < (1 << N); i++)
            if( (i & (1 << j)) != 0 )
                dp2[i] += dp2[i ^ (1 << j)];

    for(q = 1; q <= Q; q++)
    {
        scanf("%s\n", s);
        reverse(s, s + N);
        cnt[0] = cnt[1] = cnt[2] = 0;
        for(j = 0; j < N; j++)
        {
            if(s[j] == '0') cnt[0]++;
            else if(s[j] == '1')    cnt[1]++;
            else if(s[j] == '?')    cnt[2]++;
        }

        if(cnt[0] < cnt[1] && cnt[0] < cnt[2])
        {
            msk = 0;
            B = 0;
            for(i = 0; i < N; i++)
            {
                if(s[i] == '1') msk |= (1 << i);
                if(s[i] == '0') b[B++] = i;
            }

            ans = 0;
            bck0(0, msk, 1);
            printf("%d\n", ans);
        }
        else if(cnt[1] < cnt[2])
        {
            msk = 0;
            B = 0;
            for(i = 0; i < N; i++)
            {
                if(s[i] == '1')
                {
                    msk |= (1 << i);
                    b[B++] = i;
                }
                if(s[i] == '?')
                    msk |= (1 << i);
            }

            ans = 0;
            bck1(0, msk, 1);
            printf("%d\n", ans);
        }
        else
        {
            msk = 0;
            B = 0;
            for(i = 0; i < N; i++)
            {
                if(s[i] == '?') b[B++] = i;
                else    msk |= ((s[i] - '0') << i);
            }

            ans = 0;
            bckq(0, msk);
            printf("%d\n", ans);
        }
    }

    return 0;
}
accuracy: 1
time_ms: 680
memory_kb: 16564
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int L = 20;

void fill(int l, int *totals0, int *totals1, char *s) {
    if (l == 0) {
        totals0[0] = s[0];
        totals1[0] = s[0];
    } else {
        l--;
        int *totalz0 = totals0 + (1 << l);
        int *totalz1 = totals1 + (1 << l);
        char *z = s + (1 << l);
        fill(l, totals0, totals1, s);
        fill(l, totalz0, totalz1, z);
        for (int i = 0; i < 1 << l; i++) {
            totalz0[i] += totals0[i];
            totals1[i] += totalz1[i];
        }
    }
}

char vals[(1 << L) + 11];
int totals0[1 << L], totals1[1 << L], bitc[1 << L];
char word[L + 11];
int main() {
    int l, q;
    scanf("%d%d%s", &l, &q, vals);
    int all = (1 << l) - 1;
    for (int i = 0; i < 1 << l; i++) vals[i] -= '0';
    for (int i = 1; i < 1 << l; i++) bitc[i] = bitc[i >> 1] + (i & 1);
    fill(l, totals0, totals1, vals);
    while (q--) {
        scanf("%s", word);
        assert(strlen(word) == l);
        int c0 = 0, c1 = 0, cq = 0, s = 0, ans = 0;
        for (int i = 0, j = l - 1; i < l; i++, j--) {
            (word[i] == '0' ? c0 : word[i] == '1' ? c1 : cq) |= 1 << j;
        }
        if (bitc[c0] <= min(bitc[c1], bitc[cq])) {
            do ans += (bitc[s] & 1 ? -1 : 1) * totals1[s | c1]; while (s = s - 1 & c0);
        } else if (bitc[c1] <= min(bitc[c0], bitc[cq])) {
            do ans += (bitc[s] & 1 ? -1 : 1) * totals0[(s | c0) ^ all]; while (s = s - 1 & c1);
        } else {
            do ans += vals[c1 | s]; while (s = s - 1 & cq);
        }
        printf("%d\n", ans);
    }
}
accuracy: 1
time_ms: 550
memory_kb: 16520
final_rank: 3

code_snippet: #include <cstdio>
#pragma warning(disable : 4996)
int N, Q, v[1048588], vx[1048588], vy[1048588], pc[75]; char s[1048588], qs[29];
int main() {
	scanf("%d%d%s", &N, &Q, s);
	for (int i = 0; i < 1 << N; ++i) {
		v[i] = s[i] - '0';
		vx[i] = v[i];
		vy[i] = v[i];
	}
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < 1 << N; ++j) {
			if ((j >> i) & 1) {
				vx[j] += vx[j - (1 << i)];
				vy[j - (1 << i)] += vy[j];
			}
		}
	}
	pc[0] = 1;
	for (int i = 1; i < 1 << (N / 3); i++) {
		pc[i] = pc[i >> 1] ^ (i & 1);
	}
	for (int i = 0; i < Q; ++i) {
		scanf("%s", qs);
		int cx = 0, cy = 0, cz = 0, sx = 0, sy = 0, sz = 0;
		for (int j = 0; j < N; ++j) {
			if (qs[N - j - 1] == '0') ++cx, sx |= 1 << j;
			if (qs[N - j - 1] == '1') ++cy, sy |= 1 << j;
			if (qs[N - j - 1] == '?') ++cz, sz |= 1 << j;
		}
		int ret = 0;
		if (3 * cz <= N) {
			for (int j = sz; j >= 0; --j) {
				j &= sz;
				ret += v[j + sy];
			}
		}
		else if (3 * cy <= N) {
			for (int j = sy, k = 0; j >= 0; --j, ++k) {
				j &= sy;
				if(pc[k]) ret += vx[j + sz];
				else ret -= vx[j + sz];
			}
		}
		else {
			for (int j = sx, k = 0; j >= 0; --j, ++k) {
				j &= sx;
				if (pc[k]) ret += vy[sx + sy - j];
				else ret -= vy[sx + sy - j];
			}
		}
		printf("%d\n", ret);
	}
	return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 16052
final_rank: 2

code_snippet: # include <iostream>
# include <algorithm>
#include <array>
# include <cassert>
#include <cctype>
#include <climits>
#include <numeric>
# include <vector>
# include <string>
# include <set>
# include <map>
# include <cmath>
# include <iomanip>
# include <functional>
# include <tuple>
# include <utility>
# include <stack>
# include <queue>
# include <list>
# include <bitset>
# include <complex>
# include <chrono>
# include <random>
# include <limits.h>
# include <unordered_map>
# include <unordered_set>
# include <deque>
# include <cstdio>
# include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <cstdint>
#include <cfenv>
//#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
constexpr long long MOD = 1000000000 + 7;
constexpr long long INF = std::numeric_limits<long long>::max();
const double PI = acos(-1);
#define fir first
#define sec second
#define thi third
#define debug(x) cerr<<#x<<": "<<x<<'\n'
typedef pair<LL, LL> Pll;
typedef pair<LL, pair<LL, LL>> Ppll;
typedef pair<LL, pair<LL, bitset<100001>>> Pbll;
typedef pair<LL, pair<LL, vector<LL>>> Pvll;
typedef pair<LL, LL> Vec2;
struct Tll { LL first, second, third; };
typedef pair<LL, Tll> Ptll;
#define rep(i,rept) for(LL i=0;i<rept;i++)
#define Mfor(i,mf) for(LL i=mf-1;i>=0;i--)
int h, w, n, m, k, s, t, q, sum, last, cnt, ans, a[1000000],dp0[1<<20], dp1[1 << 20];
string str, ss;
bool f;
char c;
int di[4][2] = { {1,0},{-1,0} ,{0,1},{0,-1} };
struct Edge { LL to,cost; };
vector<Edge>vec[10000];
void YN(bool f) {
	if (f)
		cout << "YES" << endl;
	else
		cout << "NO" << endl;
}
void yn(bool f) {
	if (f)
		cout << "Yes" << endl;
	else
		cout << "No" << endl;
}
unsigned int popcnt(unsigned long long x)
{
	x = (x & 0x5555555555555555ULL) + ((x >> 1) & 0x5555555555555555ULL);
	x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
	x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL);
	return (x * 0x0101010101010101ULL) >> 56;
}
int main() {
	cin >> n >> m;
	cin >> str;
	rep(i, 1 << n) {
		dp0[((1 << n) - 1) ^ i] = str[i]-'0';
		dp1[i] = str[i] - '0';
	}
	rep(i,n)
		rep(s, 1LL << n) {
		if ((s & (1 << i)) == 0) {
			dp0[s] += dp0[s | (1 << i)];
			dp1[s] += dp1[s | (1 << i)];
		}
	}
	rep(i, m) {
		int ma0 = 0, ma1 = 0, ma2 = 0;
		int cnt[3] = {};
		ans = 0;
		cin >> ss;
		rep(j, n)
			if (ss[n-1-j] == '0')
				ma0 += 1 << j,cnt[0]++;
			else if (ss[n-1-j] == '1')
				ma1 += 1 << j,cnt[1]++;
			else ma2 += 1 << j,cnt[2]++;

			if (cnt[0] <= n / 3) {
				Mfor(k, ma0 + 1) {
					k &= ma0;
					if (popcnt(k) % 2)ans -= dp1[k|ma1];
					else ans += dp1[k|ma1];
				}
			}
			else if (cnt[1] <= n / 3) {
				Mfor(k, ma1 + 1) {
					k &= ma1;
					if (popcnt(k) % 2)ans -= dp0[k|ma0];
					else ans += dp0[k | ma0];
				}
			}
			else {
				Mfor(k, ma2 + 1) {
					k &= ma2;
					ans += str[ma1 + k] - '0';
				}
			}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 1850
memory_kb: 12664
final_rank: 8