比较显而易见的暴力,O(2^(2n) + 2^n * 100) 就可以直接做了
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=4105; #define pb push_back inline int getint(){ int x=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x; } inline int getbit(){ int x=0; char ch=getchar(); for(;ch!='0'&&ch!='1';ch=getchar()); for(;ch=='0'||ch=='1';ch=getchar()) x=(x<<1)|(ch=='1'); return x; } void W(int x){ if(x>=10) W(x/10); putchar(x%10+'0');} vector<int> g[N][105]; int w[N],n,m,q,ans[500005],cnt[N],all,qz[105]; inline void solve(){ for(int i=0;i<=all;i++){ memset(qz,0,sizeof(qz)); for(int j=0,x;j<=all;j++){ x=w[i^j^all]; if(x<=100) qz[x]+=cnt[j]; } for(int j=0;j<=100;j++){ if(j) qz[j]+=qz[j-1]; for(int k:g[i][j]) ans[k]=qz[j]; } } } int main(){ n=getint(),m=getint(),q=getint(),all=(1<<n)-1; for(int i=n-1;i>=0;i--) w[1<<i]=getint(); for(int i=1;i<=all;i++) w[i]=w[i&-i]+w[i^(i&-i)]; for(int i=0;i<m;i++) cnt[getbit()]++; for(int i=0,X,Y;i<q;i++) X=getbit(),Y=getint(),g[X][Y].pb(i); solve(); for(int i=0;i<q;i++) W(ans[i]),puts(""); return 0; }