题意:
给定整数M L
一个字符串s
我们定义一个子串为"好"串 iff
1、长度为 M*L
2、把这个好串分成M段,每段长度为L,且每段各不相同。
且我们得到的这些好串不重复计算(即把这些好串去重)
问有几个好串
#include <stdio.h>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
typedef unsigned long long ull;
const int N = 100005;
int n, m;
char s[N];
ull base[N], has[N], bas = 31;
map<ull, int>mp;
int main(){
base[0] = 1;
for(int i = 1; i < N; i++)base[i] = base[i-1]*bas;
while(cin>>n>>m){
scanf("%s", s);
int slen = strlen(s);
has[slen] = 0;
for(int i = slen-1; i >= 0; i--)
has[i] = has[i+1]*bas+s[i]-'a'+1;
int ans = 0;
for(int i = 0; i < m && i+n*m<=slen; i++)
{
mp.clear();
for(int j = i; j < i+n*m; j+=m)
{
mp[ has[j] - has[j+m]*base[m] ] ++;
}
ans += mp.size() == n;
for(int j = i+n*m; j+m <= slen; j+=m){
ull tmp = has[j-n*m] - has[j-(n-1)*m]*base[m];
mp[tmp] --;
if(mp[tmp]==0)mp.erase(tmp);
tmp = has[j] - has[j+m]*base[m];
mp[tmp]++;
ans += mp.size() == n;
}
}
cout<<ans<<endl;
}
return 0;
}