The main idea of the title:
$n(n\le1000)$ $m(m\le5000)$ binary numbers, the $0$ number is $0$. Concatenate the numbers with $\wedge$ and $\vee$. Ask $q(q\le1000)$ times, each time a binary number $r$ of $m$ bits is given, and ask how many connection schemes make the result $r$.
Ideas:
Refer to myy's official solution:
If the operator before the $i$ number is $\wedge$, this bit is set to $1$, otherwise it is $0$, and the resulting binary number is recorded as $x$.
Considering each bit separately, for the $i$ bit, if the $j$ number is $1$, then this bit is set to $1$, otherwise it is $0$, and the resulting binary number is recorded as $b_i$.
Taking the left as the lowest bit, it is easy to prove by prefix induction that the result of the $i$ bit is $1$ if and only if $x<b_i$.
We sort $b$ from large to small, and the result is set to $c$, then the answer is not zero only if in the order of $c$, there is no $0$ in $r$ before $1$. Find the position of the first $0$ in $r$, assuming it is $k$, then the solution of $x$ must satisfy $c_k\le x<c_{k-1}$, so the answer is $c_{k-1} -c_k$.
1 #include<cstdio> 2 #include<cctype> 3 #include<climits> 4 #include<algorithm> 5 #include<sys/mman.h> 6 #include<sys/stat.h> 7 typedef long long int64; 8 class MMapInput { 9 private: 10 char *buf,*p; 11 int size; 12 public: 13 MMapInput() { 14 register int fd=fileno(stdin); 15 struct stat sb; 16 fstat(fd,&sb); 17 size=sb.st_size; 18 buf=reinterpret_cast<char*>(mmap(0,size,PROT_READ,MAP_PRIVATE,fileno(stdin),0)); 19 p=buf; 20 } 21 char getchar() { 22 return (p==buf+size||*p==EOF)?EOF:*p++; 23 } 24 }; 25 MMapInput mmi; 26 inline int getint() { 27 register char ch; 28 while(!isdigit(ch=mmi.getchar())); 29 register int x=ch^'0'; 30 while(isdigit(ch=mmi.getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 31 return x; 32 } 33 inline int getdigit() { 34 register char ch; 35 while(!isdigit(ch=mmi.getchar())); 36 return ch^'0'; 37 } 38 const int N=1001,M=5000,mod=1e9+7; 39 int pow[M],rank[M],tmp[M],a[M],sum[M]; 40 int main() { 41 const int n=getint(),m=getint(),q=getint(); 42 for(register int i=0;i<m;i++) rank[i]=i; 43 for(register int i=pow[0]=1;i<=n;i++) { 44 pow[i]=pow[i-1]*2%mod; 45 } 46 for(register int i=0;i<n;i++) { 47 int cnt[2]={-1,m-1}; 48 for(register int j=0;j<m;j++) { 49 if(!(a[j]=getdigit())) cnt[0]++; 50 sum[j]=(sum[j]+(int64)a[j]*pow[i])%mod; 51 } 52 for(register int j=m-1;~j;j--) { 53 tmp[cnt[a[rank[j]]]--]=rank[j]; 54 } 55 std::swap(rank,tmp); 56 } 57 std::reverse(&rank[0],&rank[m]); 58 for(register int i=0;i<q;i++) { 59 for(register int i=0;i<m;i++) a[i]=getdigit(); 60 int last1=INT_MIN,first0=INT_MAX; 61 for(register int i=m-1;~i;i--) { 62 if(a[rank[i]]) { 63 last1=i; 64 break; 65 } 66 } 67 for(register int i=0;i<m;i++) { 68 if(!a[rank[i]]) { 69 first0=i; 70 break; 71 } 72 } 73 if(last1>first0) { 74 puts("0"); 75 continue; 76 } 77 const int sum1=last1==INT_MIN?pow[n]:sum[rank[last1]]; 78 const int sum2=first0==INT_MAX?0:sum[rank[first0]]; 79 printf("%d\n",(sum1-sum2+mod)%mod); 80 } 81 return 0; 82 }