这题……
题解:
考虑
O
(
2
n
)
O(2^n)
O(2n)暴力枚举答案,可以分成两段,先枚举前
a
a
a位,然后算出目前匹配那些串,设为S。对每个给定的串
s
t
r
i
str_i
stri求其能匹配后面枚举出来的
2
n
−
a
2^{n-a}
2n−a个串中的哪些串,假设叫
b
i
b_i
bi,那么前a位后面能接上的就是S中的串
s
t
r
str
str对应的
b
b
b的并。
因此对
{
1
,
⋯
 
,
q
}
\{1,\cdots,q\}
{1,⋯,q}的所有子集求b的并集,可以预处理的时候分块,这样就会发现那个
2
n
q
/
32
2^nq/32
2nq/32的部分可以出掉一个常数。通过优秀的调参可以过掉本题。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
const int BS=(1<<15)+1,QC=11,QS=(1<<10)+10,N=33,Q=110;
bitset<BS> rb[QC][QS],ans;char s[Q][N];int L[QC],R[QC];
inline int ok(char *s,int v,int n)
{
rep(i,0,n-1) if(s[i]!='?'&&s[i]-'0'!=((v>>i)&1)) return 0;return 1;
}
int main()
{
// freopen("data.in","r",stdin);
int n=inn(),q=inn();
rep(i,1,q) scanf("%s",s[i]);
int a=min(n,15),b=n-a,qs=10,qc=(q-1)/qs+1;
// debug(a)sp,debug(b)sp,debug(qs)sp,debug(qc)ln;
rep(i,1,qc)
{
L[i]=(i-1)*qs+1,R[i]=min(i*qs,q);
rep(j,L[i],R[i]) rep(k,0,(1<<b)-1)
if(ok(s[j]+a,k,b)) rb[i][1<<(j-L[i])].set(k);
rep(j,1,(1<<(R[i]-L[i]+1))-1)
{
int k=j&(-j);if(j==k) continue;
rb[i][j]=rb[i][j^k]|rb[i][k];
}
}
int Ans=0;
rep(i,0,(1<<a)-1)
{
ans.reset();
rep(j,1,qc)
{
int t=0;
rep(k,L[j],R[j]) if(ok(s[k],i,a)) t|=1<<(k-L[j]);
ans|=rb[j][t];
}
Ans+=ans.count();
}
return !printf("%d\n",Ans);
}