题意:找出有多少个M * L长度的串,串的M个连续长度为L的子串都不相同。
思路:直接hash,选取一个起始位置(1 ~ L),然后每L个L个hash一下,然后类似与尺取,取m个,看是否是m个字符的hash值都不同。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
typedef long long ll;
typedef unsigned long long ull;
char s[maxn];
const ull D = 131;
ull a[maxn],base[maxn];
map<ull,int>ms;
int M,L;
ull get_hash(int x)
{
return a[x + L - 1] - a[x - 1] * base[L];
}
int main()
{
base[0] = 1;
for(int i = 1; i < maxn; i ++)base[i] = base[i - 1] * D;
while( ~ scanf("%d%d",&M,&L))
{
scanf("%s",s + 1);int len = strlen(s + 1);
a[0] = 0;
for(int i = 1; i <= len;i ++)a[i] = a[i - 1] * D + s[i];
int ans = 0;
for(int i = 1;i <= L && i + M * L - 1 <= len ;i ++)
{
ms.clear();
for(int j = i,t = 1;t <= M; j += L,t ++)
{
ms[get_hash(j)] ++;
}
if(ms.size() == M){ans ++;}
for(int j = i + M * L ;j + L - 1<= len;j += L)
{
ull x = get_hash(j - M * L);
ms[x] --;
if(!ms[x])ms.erase(x);
ms[get_hash(j)] ++;
if(ms.size() == M){ans ++;}
}
}
printf("%d\n",ans);
}
return 0;
}