一个很妙的做法:
我们都很清楚&1和|0是没有用的,所以我们可以发现,如果把&看成1,|看成0,则一个使某一位运算结果为1的& 和 | 组成的二进制序列必须小于所有数的这一位组成的序列
所以就排个序查就行了
Code:
#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
inline int read(){
int res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
const int N=1005,M=5005;
char s[M];
int n,m,q,bin[N],pos[M];
struct str{int id,wei[N],val;}b[M];
inline bool cmp(str a,str b){
for(int i=n-1;i>=0;i--){
if(a.wei[i]>b.wei[i]) return 1;
else if(a.wei[i]<b.wei[i]) return 0;
}
return 0;
}
int main(){
n=read();m=read();q=read();
bin[0]=1;
for(int i=1;i<=n;i++) bin[i]=bin[i-1]*2%mod;
for(int i=0;i<n;i++){
scanf("%s",s+1);
for(int j=1;j<=m;j++)
b[j].wei[i]=s[j]-'0',(b[j].val+=b[j].wei[i]*bin[i])%=mod;
}
for(int i=1;i<=m;i++) b[i].id=i;
sort(b+1,b+m+1,cmp);
for(int i=1;i<=m;i++) pos[b[i].id]=i;
b[0].val=bin[n];
while(q--){
scanf("%s",s+1);
int minn=m+1,maxn=0;
for(int i=1;i<=m;i++)
if(s[i]=='0') minn=min(minn,pos[i]);
else maxn=max(maxn,pos[i]);
if (maxn>minn) puts("0");
else cout<<(b[maxn].val+mod-b[minn].val)%mod<<"\n";
}
}