CF1017D The Wu 暴力

题意翻译

给长度=N的w数组w[1...N],定义2个长度=N的01串s,t之间构成的答案 = sigma{w[i]}, i=1..N且s[i]==t[i]。

给定长度=N的01串的multiset S,每次给01串t和K值,询问S中和t串构成答案<=K的s串数量。

题目描述

Childan is making up a legendary story and trying to sell his forgery — a necklace with a strong sense of "Wu" to the Kasouras. But Mr. Kasoura is challenging the truth of Childan's story. So he is going to ask a few questions about Childan's so-called "personal treasure" necklace.

This "personal treasure" is a multiset S S S of m m m "01-strings".

A "01-string" is a string that contains n n n characters "0" and "1". For example, if n=4 n=4 n=4 , strings "0110", "0000", and "1110" are "01-strings", but "00110" (there are 5 5 5 characters, not 4 4 4 ) and "zero" (unallowed characters) are not.

Note that the multiset S S S can contain equal elements.

Frequently, Mr. Kasoura will provide a "01-string" t t t and ask Childan how many strings s s s are in the multiset S S S such that the "Wu" value of the pair (s,t) (s, t) (s,t) is not greater than k k k .

Mrs. Kasoura and Mr. Kasoura think that if si=ti s_i = t_i si​=ti​ ( 1≤i≤n 1\leq i\leq n 1≤i≤n ) then the "Wu" value of the character pair equals to wi w_i wi​ , otherwise 0 0 0 . The "Wu" value of the "01-string" pair is the sum of the "Wu" values of every character pair. Note that the length of every "01-string" is equal to n n n .

For example, if w=[4,5,3,6] w=[4, 5, 3, 6] w=[4,5,3,6] , "Wu" of ("1001", "1100") is 7 7 7 because these strings have equal characters only on the first and third positions, so w1+w3=4+3=7 w_1+w_3=4+3=7 w1​+w3​=4+3=7 .

You need to help Childan to answer Mr. Kasoura's queries. That is to find the number of strings in the multiset S S S such that the "Wu" value of the pair is not greater than k k k .

输入输出格式

输入格式:

The first line contains three integers n n n , m m m , and q q q ( 1≤n≤12 1\leq n\leq 12 1≤n≤12 , 1≤q,m≤5⋅105 1\leq q, m\leq 5\cdot 10^5 1≤q,m≤5⋅105 ) — the length of the "01-strings", the size of the multiset S S S , and the number of queries.

The second line contains n n n integers w1,w2,…,wn w_1, w_2, \ldots, w_n w1​,w2​,…,wn​ ( 0≤wi≤100 0 \le w_i \le 100 0≤wi​≤100 ) — the value of the i i i -th caracter.

Each of the next m m m lines contains the "01-string" s s s of length n n n — the string in the multiset S S S .

Each of the next q q q lines contains the "01-string" t t t of length n n n and integer k k k ( 0≤k≤100 0\leq k\leq 100 0≤k≤100 ) — the query.

输出格式:

For each query, print the answer for this query.

输入输出样例

输入样例#1: 复制

2 4 5
40 20
01
01
10
11
00 20
00 40
11 20
11 40
11 60

输出样例#1: 复制

2
4
2
3
4

输入样例#2: 复制

1 2 4
100
0
1
0 0
0 100
1 0
1 100

输出样例#2: 复制

1
2
1
2

说明

In the first example, we can get:

"Wu" of ("01", "00") is 40 40 40 .

"Wu" of ("10", "00") is 20 20 20 .

"Wu" of ("11", "00") is 0 0 0 .

"Wu" of ("01", "11") is 20 20 20 .

"Wu" of ("10", "11") is 40 40 40 .

"Wu" of ("11", "11") is 60 60 60 .

In the first query, pairs ("11", "00") and ("10", "00") satisfy the condition since their "Wu" is not greater than 20 20 20 .

In the second query, all strings satisfy the condition.

In the third query, pairs ("01", "11") and ("01", "11") satisfy the condition. Note that since there are two "01" strings in the multiset, the answer is 2 2 2 , not 1 1 1 .

In the fourth query, since k k k was increased, pair ("10", "11") satisfies the condition too.

In the fifth query, since k k k was increased, pair ("11", "11") satisfies the condition too.


m,q 都很大,但是 n 却很小,自然联想到 2^n 枚举;

考虑 dp[ i ][ j ]表示当需要匹配的10进制为 i 时,约束量<=j 时的方案数;

所以我们可以 2^{12}去枚举,预处理出来;

然后再将 0~ k 的方案数累加即可;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 500005
#define inf 0x3f3f3f3f
#define INF 999999999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const int mod = 10000007;
#define Mod 20100403
#define sq(x) (x)*(x)
#define eps 1e-7
typedef pair<int, int> pii;
#define pi acos(-1.0)
const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
inline int rd() {
    int x = 0;
    char c = getchar();
    bool f = false;
    while (!isdigit(c)) {
        if (c == '-') f = true;
        c = getchar();
    }
    while (isdigit(c)) {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return f ? -x : x;
}

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

int n, m, q;
int cnt[maxn];
int dp[5000][200];
int wu[maxn];


int main()
{
    //ios::sync_with_stdio(false);
    rdint(n); rdint(m); rdint(q);
    for (int i = 1; i <= n; i++)rdint(wu[i]);
    for (int i = 1; i <= m; i++) {
        char ch[20]; rdstr(ch);
        int tmp = 0;
        for (int j = 0; j < n; j++)if (ch[j] == '1')tmp += (1 << (j));
        cnt[tmp]++;
    }
    int i, j;
    for (i = 0; i < (1 << 12); i++) {
        
        for (j = 0; j < (1 << 12); j++) {
            int tmp = 0;
            for (int k = 0; k < n; k++) {
                if ((i&(1 << k)) == (j&(1 << k)))tmp += wu[k + 1];
        
                
            }
            if (tmp <= 100)dp[i][tmp] += cnt[j];
        }
        
    }
    while (q--) {
        char ch[20]; int k; rdstr(ch); rdint(k);
        int tmp = 0;
        for (int i = 0; i < n; i++)if (ch[i] == '1')tmp += (1 << (i));
        int ans = 0;
        for (int i = 0; i <= k; i++)ans += dp[tmp][i];
        printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40273481/article/details/83211110
wu