分析
除了第一个数外,以编号最小的为最低位,把每一个数的第i位拿出来组成一个n位二进制数,设为bi。
对于所填的运算符,设or为0,and为1,拿出来也会组成一个nn位二进制数,设为x。
神奇的地方来了,该位运算结果为1当且仅当bi>x。
那么我们就可以把bibi从大到小排序,对于每个询问,其答案不为0当且仅当不存在某个1在0的后面。否则就找到第一个0,设为第i位,那么答案就是bi−1−bi。
Code
#include <bits/stdc++.h>
const int N = 1005;
const int M = 5005;
const int MOD = 1000000007;
int n,m,q,bin[N],pos[M];
struct data
{
int id,s[N],val;
}b[M];
char str[M];
bool cmp(data a,data b)
{
for (int i = n - 1; i >= 0; i--)
if (a.s[i] > b.s[i])
return 1;
else if (a.s[i] < b.s[i])
return 0;
return 0;
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
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",str + 1);
for (int j = 1; j <= m; j++)
b[j].s[i] = str[j] - '0', (b[j].val += b[j].s[i] * bin[i]) %= MOD;
}
for (int i = 1; i <= m; i++)
b[i].id = i;
std::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",str + 1);
int mn = m + 1, mx = 0;
for (int i = 1; i <= m; i++)
if (str[i] == '0')
mn = std::min(mn,pos[i]);
else mx = std::max(mx,pos[i]);
if (mx > mn)
printf("%d\n",0);
else printf("%d\n",(b[mx].val + MOD - b[mn].val) % MOD);
}
}