原题链接:
https://vjudge.net/problem/HDU-4821
AC代码:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int INF = 0x3fffffff;
typedef long long ll;
typedef unsigned long long ull;
void __init__()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
}//head
const ll maxn = 1e5 + 10;
const int p = 1331;
char s[maxn];
ull base[maxn];
ull hasH[maxn];
void get_base()
{
base[0] = 1;
for (int i = 1; i < maxn; i++)
{
base[i] = base[i - 1] * p;
}
}
void get_hash(int len, char s[])
{
for (int i = 1; i <= len; i++)
{
hasH[i] = hasH[i - 1] * p + s[i] - 'a';
}
}
ull get_subhash(int l, int r)
{
return hasH[r] - hasH[l - 1] * base[r - l + 1];
}
int main()
{
// __init__();
get_base();
int l, m;
while (scanf("%d%d", &m, &l) != EOF)
{
cin >> s + 1;
int len = strlen(s + 1);
get_hash(len, s);
int ans = 0;
for (int i = 1; i <= l && i + l * m <= len; i++)
{
map<ull, int> hsmp;
for (int j = i; j <= i + l * m - 1; j += l)
{
ull x = get_subhash(j, j + l - 1);
hsmp[x]++;
}
if (hsmp.size() == m)
{
ans++;
}
for (int j = i + l * m; j + l - 1 <= len; j += l)
{
ull x = get_subhash(j, j + l - 1);
hsmp[x]++;
x = get_subhash(j - l * m, j - l * m + l - 1);
hsmp[x]--;
if (hsmp[x] == 0)
hsmp.erase(x);
if (hsmp.size() == m)
{
ans++;
}
}
}
printf("%d\n", ans);
}
return 0;
}
日常补题,跟大佬学到了字符串哈希的用法,为了优化时间复杂度,遍历采用了尺取法进行遍历。