The meaning of the question is relatively simple. For two N-long strings s,t, they will match and produce "Wu" according to the following rules. The rules are as follows:
if si == ti : res += wi;
There will be a synthesis. Then the question is to give you m strings of length N and Q questions. For each question, give you T strings of length N and the integer K. Ask you how many of the M strings match the string to produce "Wu" less than k
Idea: because N < = 12, there are only 4096 middle strings at most. For each N, we find "Wu" generated by any two strings, and record it. Then, for
The w strings provided are de duplicated and the number of times of each string is recorded. Because of this problem, w < = 100, and therefore the largest "Wu" generated is 1200, so we maintain an array book[i][j] to represent the string number I, and how many strings of J "Wu" generated in W. Because the Wu generated by any two strings is preprocessed in advance, the complexity here is only 4096 * 4096, because there are only 4096 different strings at most. So let's find the prefix sum again. For each inquiry, directly find the number of T, then book[t][k] is the inquiry result.
The code is as follows:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 4100;
const int MAX_M = 5e5+10;
int Weight[MAX];
string tostring(int x,int len){
string res = "";
while(x > 0){
res += (x%2+'0');
x /= 2;
}
for(int i=res.length();i<len;++i){
res += '0';
}
reverse(res.begin(),res.end());
return res;
}
char Integer[MAX][13];
int N,M,Q;
int G[MAX][MAX];
int getvalue(int u,int v){
int res = 0;
for(int i=0;i<N;++i){
if(Integer[u][i] == Integer[v][i])
res += Weight[i];
}
return res;
}
void init(){
int Max = pow(2,N);
for(int i=0;i<Max;++i){
string str = tostring(i,N);
for(int j=0;j<N;++j){
Integer[i][j] = str[j];
}
Integer[i][N] = '\0';
}
for(int i=0;i<Max;++i){
for(int j=i;j<Max;++j){
int sum = 0;
for(int k=0;k<N;++k){
if(Integer[i][k] == Integer[j][k])
sum += Weight[k];
}
G[i][j] = G[j][i] = sum;
}
}
}
int toint(char *str){
int res = 0;
for(int i=0;i<N;++i){
res = res*2 + str[i]-'0';
}
return res;
}
int book[MAX][1333];
int gettime[MAX];
int id[MAX_M];
bool cmp(char A[13],char B[13]){
return strcmp(A,B) == -1;
}
int main(void){
scanf("%d%d%d",&N,&M,&Q);
for(int i=0;i<N;++i){
scanf("%d",&Weight[i]);
}
init();
char str[30];
for(int i=0;i<M;++i){
scanf("%s",str);
int v = toint(str);
id[i] = v;
}
sort(id,id+M);
int cnt = 0;
int last = 0;
for(int i=0;i<M;++i){
if(i == 0 || id[i] != id[i-1]){
last = id[i];
id[cnt++] = last;
gettime[last] = 1;
}
else{
gettime[last]++;
}
}
int Max = pow(2,N)-1;
for(int i=0;i<=Max;++i){
for(int j=0;j<cnt;++j){
int value = G[i][id[j]];
book[i][value] += gettime[id[j]];
}
for(int j=1;j<=1200;++j){
book[i][j] += book[i][j-1];
}
}
char t[15];
int k;
long long res = 0;
for(int i=1;i<=Q;++i){
scanf("%s%d",t,&k);
int v = toint(t);
printf("%d\n",book[v][k]);
}
return 0;
}