题目大意,给出子串长度n,字串中出现的字符个数nc,,下一行给出整个字串,找出共有多少个不同的子串,子串个数不超过16m;
Sample Input
3 4 daababac
Sample Output
5题目分析:字符串哈希,用字串中字符个数nc进制,统计出每n个字符对应的nc进制数值。
先找到第一组子串对应的hash值,hn,然后循环,一边对数组取nc^(n_1)模,一边求下一个子串的hash值。实际上用的桶排序。
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int maxn=16000000+7;
char s[1000000];
int n,m,k,t;
int num[260],ans=0;
bool hash[maxn]={0};
int main(){
scanf("%d%d",&n,&m);
scanf("%s",s);
k=0;
memset(num,-1,sizeof(num));//找出进制对应数字;
for(int i=0;k<m;i++){
if(num[s[i]]==-1)num[s[i]]=k++;
}
int l=strlen(s);
int hn=0;
if(n>l){
printf("0\n");return 0;
}
int high=1;ans=1;
for(int i=0;i<n;i++){ //找到第一组子串
hn=hn*m+num[s[i]];
high*=m;
}
hash[hn]=true;
high/=m;
for(int i=n;i<l;i++){
hn%=high;//去掉最高位
hn=hn*m+num[s[i]];//增加新的低位
if(!hash[hn])ans++;
hash[hn]=true;
}
printf("%d\n",ans);
return 0;
}