题目链接: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;
}