原题:http://codeforces.com/contest/271/problem/D
题解:求满足要求的本质不同的个数。分别枚举左右端点,子段和判断是否不超过k个坏字母,通过hash来判断是否重复。
定义hash函数
显然:
从位置k+1到长度为n的子串:
应用时用 无符号整形,自然溢出省去求模。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ull unsigned long long
using namespace std;
const int N=2e3+10,Z=26,M=1e9+7;
char s[N],str[N];
int mark[N],sum[N],n,k,cnt;
ull q[N*N];
int main(){
// freopen("cf166d.in","r",stdin);
scanf("%s%s",s+1,str);n=strlen(s+1);
scanf("%d",&k);
for(int i=1;i<=n;i++) if(str[s[i]-'a']=='0') sum[i]=1;
for(int i=1;i<=n;i++) sum[i]+=sum[i-1];
cnt=0;
for(int i=1;i<=n;i++){
ull hash=0;
for(int j=i;j<=n;j++){
if(sum[j]-sum[i-1]>k) break;
hash=(hash*M+s[j]-'a'+1);
q[cnt++]=hash;
}
}
sort(q,q+cnt);
printf("%d\n",unique(q,q+cnt)-q);
return 0;
}