nowcoder119E A Simple Problem

题意:输入一个长度为n的字符串和一个长度为m的字符串,第二个串的相同的字母可以变化为其他字符,不同字符不能变为相同的字符,问能有多少个字符串能匹配

题解:可以对模式串预处理求同一个字符的哈希值,匹配的时候对应的位置要相同,所以可以快速计算出第二个串的哈希值,匹配就可以

#include <bits/stdc++.h>
#define maxn 200100
using namespace std;
typedef unsigned long long ull;
int a[maxn], dir[15], n, k, m, b[maxn], p[15], na[15];
ull hb[maxn], ha, hh, sum[15], B =1e9+7, ff;
int main(){
    scanf("%d%d", &n, &k);
    for(int i=0;i<n;i++) scanf("%d", &a[i]);
    scanf("%d", &m);
    hb[0] = 1;
    memset(p, -1, sizeof(p));
    for(int i=0;i<m;i++){
        scanf("%d", &b[i]);
        if(i) hb[i] = hb[i-1]*B;
        p[b[i]] = i;
    }
    if(m > n){
        printf("0\n");
        return 0;
    }
    for(int i=0;i<m;i++){
        sum[b[i]] += hb[m-1-i];
        ha = ha*B+a[i];
    }
    int ans = 0;
    for(int i=0;i+m<=n;ha = (ha-hb[m-1]*a[i])*B+a[i+m], i++){
        memset(na, 0, sizeof(na));
        memset(dir, 0, sizeof(dir));
        int j = 0;
        for(j=0;j<k;j++){
            if(p[j] != -1){
                na[j] = a[p[j]+i];
                if(dir[na[j]] == 0) dir[na[j]] = 1;
                else break;
            }
        }
        if(j < k) continue;
        hh = 0;
        for(j=0;j<k;j++) hh = hh+na[j]*sum[j];
        if(hh == ha) ans++;
    }
    printf("%d\n", ans);
    return 0;
}
/*
6 3
1 2 2 2 2 1
2
1 2
*/

 

posted on 2018-05-08 13:30  2855669158  阅读(205)  评论(0编辑  收藏  举报

导航