题目链接:http://poj.org/problem?id=1200
题目大意:
给你一个n和nc,以及一个字符串s,保证字符串里出现的字符种类等于nc。
让你求长度为n的字符串种类。
题目保证可能的字符集出现的子串最大数量不超过160万。
思路:直接暴力把哈希值加入set,输出st.size(),复杂度O(n*logn),T了。
发现这个如果把nc作为进制,子串最大数量不超过160万,那么这个哈希值一定不会冲突并且不超过160万。那么就可以用vis判断是否存在就ok了,时间复杂度O(n*nc)这题坑点就是没有说n和nc范围。
这个时候,防止溢出,子串不能用前缀和求,前缀和会爆,只能每次求n个。
先把字符编号,然后作为nc进制求哈希值就行了。
#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
char s[16000010];
bool vis[16000010]={0};
int id[1010]={0};
int main()
{
memset(id, -1, sizeof(id));
int n, m, cut=0;
scanf("%d%d",&n,&m);
scanf("%s",s+1);
int Len=strlen(s+1);
for(int i=1;i<=Len;i++)
{
if(id[s[i]]==-1)//编号
{
id[s[i]]=cut++;
}
}
int re=0;
for(int i=1;i<=Len-n+1;i++)
{
ull ans=0;
for(int j=i;j<i+n;j++)
{
ans+=ans*m+id[s[j]];
}
if(vis[ans]==0)
{
re++;
vis[ans]=1;
}
}
printf("%d\n",re);
return 0;
}