* ! AHOI/HNOI2018寻宝游戏
作者:互联网
x&0=0,x|1=1
我们把\(\&\to0,|\to1\),把操作用01串代替
于是转化为比大小的题目
桶排然后记录每个串的值方便求答案
时间复杂度\(O(nm)\)
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
const int N=5004,mod=1e9+7;
int n,m,Q,mi[N],c[2],a[N],b[N],sa[N];
char s[N];
int main(){
n=read();m=read();Q=read();
mi[1]=1;
for(int i=2;i<=n+1;i++)mi[i]=(mi[i-1]<<1)%mod;
for(int i=1;i<=m;i++)sa[i]=i;
for(int i=1;i<=n;i++){
scanf("%s",s+1);
reverse(s+1,s+m+1);
c[1]=m;c[0]=0;
for(int j=1;j<=m;j++)
if(s[j]=='1')a[j]=(a[j]+mi[i])%mod;
else c[0]++;
for(int j=m;j;j--)
b[c[s[sa[j]]^48]--]=sa[j];
swap(b,sa);
}
for(int i=1;i<=m;i++)b[i]=a[sa[i]];
b[m+1]=mi[n+1];
while(Q--){
scanf("%s",s+1);
reverse(s+1,s+m+1);
int up=m+1,dw=0;
for(int i=m;i;i--)
if(s[sa[i]]=='0'){dw=i;break;}
for(int i=1;i<=m;i++)
if(s[sa[i]]=='1'){up=i;break;}
if(up<dw)puts("0");
else cout<<(b[up]-b[dw]+mod)%mod<<"\n";
}
return (0-0);
}
标签:AHOI,int,复杂度,寻宝,while,isdigit,HNOI2018,getchar 来源: https://www.cnblogs.com/aurora2004/p/12600694.html