http://cplusoj.com/d/senior/p/NODSX2302B
考虑 b i ∈ { 1 } b_i\in\{1\} bi∈{1} 怎么做,这是个裸的FWT,FWT后弄个快速幂就行
如果 b i ∈ { 0 , 1 } b_i\in\{0,1\} bi∈{0,1},在0的位我们就要保持原样不能动
若 b i ∈ { 0 , 1 , 2 , 3 } b_i\in\{0,1,2,3\} bi∈{0,1,2,3},同理,在对应的位置上我们实行对应的操作。也就是把FWT的每一层弄成 b b b 指定的操作即可。
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stdout, ##__VA_ARGS__)
#define debag(...) fprintf(stderr, ##__VA_ARGS__)
#else
#define debug(...) void(0)
#define debag(...) void(0)
#endif
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
#define fi first
#define se second
//#define M
#define mo (int)(1e9 + 7)
#define N 2000010
int pw(int a, int b) {
int ans = 1;
while(b) {
if(b & 1) ans *= a;
a *= a; b >>= 1;
ans %= mo; a %= mo;
}
return ans;
}
const int inv2 = pw(2, mo-2);
int n, m, i, j, k, T;
int A[N], a[N], b[N], o, P, l;
char str[N];
void cp() {
for(i = 0; i < n; ++i) a[i] = A[i];
}
void FWT(int *f, int x) {
for(k = 1, o = 2, l = 0; o <= n; o <<= 1, k <<= 1, ++l) {
if(b[l] == 1) {
for(i = 0; i < n; i += o)
for(j = 0; j < k; ++j)
f[i + j + k] = (f[i + j + k] + f[i + j] * x) % mo;
}
if(b[l] == 2) {
for(i = 0; i < n; i += o)
for(j = 0; j < k; ++j)
f[i + j] = (f[i + j] + f[i + j + k] * x) % mo;
}
if(b[l] == 3) {
for(i = 0; i < n; i += o)
for(j = 0; j < k; ++j) {
int y = (x == 1 ? 1 : inv2);
f[i + j] += f[i + j+ k];
f[i + j + k] = f[i + j] - 2 * f[i + j + k];
f[i + j] = f[i + j] * y % mo;
f[i + j + k] = f[i + j + k] * y % mo;
}
}
}
debug("l : %lld\n", l);
assert(l == m);
}
void mul() {
for(i = 0; i < n; ++i) a[i] = pw(a[i], P);
}
signed main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
// srand(time(NULL));
// T=read();
// while(T--) {
//
// }
P = read(); m = read(); n = (1 << m);
scanf("%s", str);
for(i = 0; i < n; ++i) A[i] = str[i] - '0';
for(i = 0; i < m; ++i) b[i] = read();
for(i = 0; i < n; ++i) debug("%lld ", A[i]); debug("\n");
cp(); FWT(a, 1);
for(i = 0; i < n; ++i) debug("%lld ", a[i]); debug("\n");
mul(); FWT(a, -1);
int q = read();
while(q--) {
int x = read();
printf("%lld\n", (a[x] % mo + mo) % mo);
}
return 0;
}