luogu P3370
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
typedef unsigned long long ull;
int n;
char str[1510];
set<ull> S;
ull str_hash(char str[]) //2^64自然溢出
{
int base=131, len=strlen(str);
ull ans=0;
for(int i=0; i<len; i++)
ans=ans*base+ull(str[i]-'a'+1); //或 ans=ans*base+ull(str[i]) 直接使用ASCII码
return ans;
}
int main()
{
scanf("%d", &n);
for(int i=1; i<=n; i++) scanf("%s", str), S.insert(str_hash(str));
printf("%d\n", S.size()); //统计方法还可以将全部哈希值顺序存储到一个数组中,排序后计算不重复值
return 0;
}
loj.ac 103
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef unsigned long long ull;
char A[1000010], B[1000010];
ull H[1000010], hash_b, power[1000010];
const int BASE=131;
ull str_hash(char str[]) //2^64自然溢出
{
ull ans=0;
int len=strlen(str);
for(int i=0; i<len; i++)
ans=ans*BASE+ull(str[i]-'a'+1); //或 ans=ans*BASE+ull(str[i]) 直接使用ASCII码
return ans;
}
int main()
{
int len_A, len_B, nsub, ans=0;
scanf("%s%s", A, B);
len_A=strlen(A), len_B=strlen(B), nsub=len_A-len_B+1; //nsub为最大匹配次数(可匹配字串数量)
hash_b=str_hash(B); //计算匹配串的哈希值
power[0]=1;
for(int i=1; i<=1000000; i++) power[i]=power[i-1]*BASE; //计算BASE^n
H[1]=ull(A[0]-'a'+1);
for(int i=2; i<=len_A; i++) H[i]=H[i-1]*BASE+ull(A[i-1]-'a'+1); //计算A的前缀的hash值
for(int i=1; i<=nsub; i++)
if(hash_b==H[i+len_B-1]-H[i-1]*power[len_B]) ans++; //hash_b和A中所有的子串hash值匹配
printf("%d\n", ans);
return 0;
}