Codeforce 1017D The Wu 预处理,二维前缀和

The Wu

题 意:给你m个长度为n个01串t,q个长度为n的查询串s,如果ti = si 则他们的价值为wi,否则为0,pair< t ,s >的总价值为各个字符的价值之和。

数据范围:
1<=n<=12
1<=q,m<=5e5
0<=wi<=100

输入样例:

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

输出样例:

2
4
2
3
4

思 路:先把每一个01串转化成对应的数字,预处理所有可能询问的串和已经有的串。
收 获:又多学习了一种字符串的解题姿势,见识了二维前缀和。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 12;
int sum[1<<maxn+1][105];
int a[maxn+1];
int cnt[1<<maxn+1];
char s[maxn+1];
int n,m,q,k;
int main(){
    scanf("%d %d %d",&n,&m,&q);
    for(int i=0;i<n;i++)scanf("%d",&a[i]);
    for(int i=0;i<m;i++){
        scanf("%s",s);
        int tmp = 0;
        for(int j=0;j<n;j++){
            tmp |= ((s[j]-'0')<<j);
        }
        cnt[tmp]++;
    }
    for(int i=0;i<(1<<n);i++){
        for(int j=0;j<(1<<n);j++){
            int tmp = 0;
            for(int k=0;k<n;k++){
                if((i&(1<<k)) ==(j&(1<<k))) tmp+=a[k];  
            }
            if(tmp > 100) continue;
            sum[i][tmp] += cnt[j];
        }
    }
    for(int i=0;i<(1<<n);i++){
        for(int j=1;j<=100;j++){
            sum[i][j] += sum[i][j-1];
        }
    }
    for(int i=0;i<q;i++){
        scanf("%s%d",s,&k);
        int tmp = 0;
        for(int j=0;j<n;j++){
            tmp|=((s[j]-'0')<<j);
        }
        printf("%d\n",sum[tmp][k]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37129433/article/details/81557931
wu
今日推荐