题解:P3370 【模板】字符串哈希
LastKismet · · 题解
这里提供 XorShift 哈希方式。
我们考虑哈希字符串的形态,不难想到,前
我们会考虑对
但多项式映射的冲突率是很高的。所以这里提供一种冲突率极低的方式,也就是 XorShift。
事实上,这是一个伪随机数生成算法。我们可以利用其周期长的特性进行映射。
关于那三次位移的常量,实测换成别的也够用,但是用这个经典的常量好背好写可以获得更大的周期,也就是更小的冲突率。
const ull mask=mt19937_64(time(0))();
ull shift(ull x){
x^=mask;
x^=x<<13;
x^=x>>17;
x^=x<<5;
x^=mask;
return x;
}
其实那两次对随机常量
然后是关键部分代码:
const ull mask=mt19937_64(time(0))();
ull shift(ull x){
x^=mask;
x^=x<<13;
x^=x>>17;
x^=x<<5;
x^=mask;
return x;
}
set<ull> hshs;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n;cin>>n;
string s;
rep(i,1,n){
cin>>s;
ull hsh=0;
for(auto c:s)hsh=shift(hsh)+c;
hshs.insert(hsh);
}
cout<<hshs.size();
return 0;
}
代码中对当前位的更新使用了直接加的方式,事实上直接异或也没有问题,以及别的杂七杂八的更新方法多半都没有问题,是自由的。