题意:给出一个字符串和字符串中出现字符的种数,求该串有多少个长度为n的互不相同的子串。
分析:karp-rabin把字符串转化成数字的算法,一个字符串有n种字符构成,把每种字符对应为0~n-1中的一个数字,把字母换成对应的数字之后,对于固定长度的串,每个串都与一个唯一的n进制数对应。这样就可以hash了

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
usingnamespace std;
#define maxn 16000005
bool hash[maxn];
int name[260];
int n, nc;
char st[maxn];
int main()
{
//freopen("t.txt", "r", stdin);
scanf("%d%d%s", &n, &nc, st);
memset(name, 0, sizeof(name));
memset(hash, 0, sizeof(hash));
int len = strlen(st);
int t =0;
for (int i =0; i < len; i++)
if (name[st[i]] ==0)
name[st[i]] = t++;
int temp =0;
t = nc;
for (int i =0; i < n -1; i++)
{
temp = temp * nc + name[st[i]];
t *= nc;
}
int ans =0;
for (int i = n -1; i < len; i++)
{
temp = (temp * nc + name[st[i]]) % t;
if (!hash[temp])
{
ans++;
hash[temp] =true;
}
}
printf("%d\n", ans);
return0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
usingnamespace std;
#define maxn 16000005
bool hash[maxn];
int name[260];
int n, nc;
char st[maxn];
int main()
{
//freopen("t.txt", "r", stdin);
scanf("%d%d%s", &n, &nc, st);
memset(name, 0, sizeof(name));
memset(hash, 0, sizeof(hash));
int len = strlen(st);
int t =0;
for (int i =0; i < len; i++)
if (name[st[i]] ==0)
name[st[i]] = t++;
int temp =0;
t = nc;
for (int i =0; i < n -1; i++)
{
temp = temp * nc + name[st[i]];
t *= nc;
}
int ans =0;
for (int i = n -1; i < len; i++)
{
temp = (temp * nc + name[st[i]]) % t;
if (!hash[temp])
{
ans++;
hash[temp] =true;
}
}
printf("%d\n", ans);
return0;
}