题意:输入一个长度为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 */