题目大意:
给定n个m位的二进制数,在每一个数前面补上一个(lor)或(land),最前面补上一个0,每次询问最后运算结果为r的方案数为多少。
思路 :
感觉MYY出的题就是不一样。
位数很多,所以应该要想到对于每一位单独考虑。
对于单独每一位,考虑每一个运算符这一位上的影响,不难发现总共有四种情况:(land 1, land 0, lor 1, lor 0),其中(land 1,lor 0)对最后的结果不会产生影响,于是我们发现(land 0)会使目前的结果为0,(lor 1)会使目前的结果为1,并且每一次的运算独立,和之前的结果并没有任何关系。
于是可以进一步得到,如果最后的结果要为1,那么最后一个有效的运算应该是(lor 1),如果是0,则最后一个有效的运算应该是(land 0)。
于是我们把操作序列的(land)看作1,(lor)看作0,并反转。然后将每一位的序列给从后往前提出来,不难发现当这一位的序列(>)opt的时候,这一位的结果为1,反之则为0。
于是我们只要对每一位的操作序列排序就好了。
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
#define DREP(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)
#define MREP(i,x) for(int i=beg[x],v;v=to[i],i;i=las[i])
#define debug(x) cout<<#x<<"="<<x<<endl
#define fi first
#define se second
#define mk make_pair
#define pb push_back
typedef long long ll;
using namespace std;
void File(){
freopen("bzoj5285.in","r",stdin);
freopen("bzoj5285.out","w",stdout);
}
template<typename T>void read(T &_){
T __=0,mul=1; char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')mul=-1;
ch=getchar();
}
while(isdigit(ch))__=(__<<1)+(__<<3)+(ch^'0'),ch=getchar();
_=__*mul;
}
const int maxn=1000+10;
const int maxm=5000+10;
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
int n,m,q,rank[maxm];
ll p2[maxn],sum[maxm];
bool t[maxm];
struct node{
int id;
bool num[maxn];
bool operator < (const node & tt) const {
REP(i,1,n)if(num[i]<tt.num[i])return 1;
else if(num[i]>tt.num[i])return 0;
return 0;
}
}a[maxm];
void init(){
read(n); read(m); read(q);
p2[0]=1;
REP(i,1,n)p2[i]=p2[i-1]*2%mod;
REP(i,1,n){
char ch=getchar();
int cnt=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))a[++cnt].num[n-i+1]=ch^'0',ch=getchar();
}
REP(i,1,m)a[i].id=i;
sort(a+1,a+m+1);
REP(i,1,m)rank[a[i].id]=i;
//REP(i,1,m)printf("%d
",rank[i]);
/*REP(i,1,m){
//printf("%d
",a[i].id);
REP(j,1,n)printf("%d",a[i].num[j]);
putchar('
');
}*/
}
void work(){
REP(i,1,n)a[m+1].num[i]=1;
REP(i,1,m+1)REP(j,1,n)if(a[i].num[j])
sum[i]=(sum[i]+p2[n-j])%mod;
++sum[m+1];
REP(ca,1,q){
char ch=getchar();
int cnt=0,L=0,R=m+1;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))t[++cnt]=ch^'0',ch=getchar();
REP(i,1,m)if(t[i])R=min(R,rank[i]);
else L=max(L,rank[i]);
//cout<<L<<" "<<R<<endl;
if(L>R)printf("0
");
else printf("%lld
",(sum[R]-sum[L]+mod)%mod);
/*REP(i,1,n)cout<<t[i];
cout<<endl;*/
}
}
int main(){
// File();
init();
work();
return 0;
}