codeforces 1017D. The Wu thought

Keywords: less

link

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;
}

Posted by Carth on Sat, 04 Jan 2020 05:48:08 -0800