哈希
质数:
超大(14位,基本上不能再大了,再大hash时乘法会爆)质数:
99999999999973,99999999999971(都是12个9)
找质数:https://zh.numberempire.com/primenumbers.php
小一点(1e9+7,1e9+9)
小一点(9位)
999999937
再小:3527;277
测试发现,并没有发现int/LL/ULL互转会消耗过多的时间(几乎无影响),同时1LL*...来转成long long也几乎没有多余消耗,因此可以放心在乘法时再临时转成LL,平时用int;不怕溢出的话,转成ULL来成比LL要快
namespace Hash { typedef unsigned long long ULL; const int md2=999999937; struct Hdata { ULL d1;int d2; Hdata(ULL a,int b):d1(a),d2(b<md2?(b<0?b+md2:b):b-md2){} Hdata():d1(0),d2(0){} }; Hdata operator*(const Hdata &a,int b) {return Hdata(a.d1*b,ULL(a.d2)*b%md2);} Hdata operator*(const Hdata &a,const Hdata &b) {return Hdata(a.d1*b.d1,ULL(a.d2)*b.d2%md2);} Hdata operator+(const Hdata &a,int b) {return Hdata(a.d1+b,a.d2+b);} Hdata operator-(const Hdata &a,const Hdata &b) {return Hdata(a.d1-b.d1,a.d2-b.d2);} bool operator==(const Hdata &a,const Hdata &b) {return a.d1==b.d1&&a.d2==b.d2;} }
Hdata hs[1000100]; const int X=131; Hdata pwx[1000100]; Hdata ghash(int l,int r) { if(l>r) return Hdata(0,0); return hs[r]-hs[l-1]*pwx[r-l+1]; }
for(i=1;i<=n;i++) hs[i]=hs[i-1]*X+s[i]; pwx[0]=Hdata(1,1); for(i=1;i<=n;i++) pwx[i]=pwx[i-1]*X;
2018.7.30
//记得调用Hash::init(); namespace Hash { typedef unsigned long long ULL; const int md2=999999937; struct Hdata { ULL d1;int d2; Hdata(ULL a,int b):d1(a),d2(b<md2?(b<0?b+md2:b):b-md2){} Hdata():d1(1),d2(1){} }; Hdata operator*(const Hdata &a,int b){return Hdata(a.d1*b,ULL(a.d2)*b%md2);} Hdata operator*(const Hdata &a,const Hdata &b){return Hdata(a.d1*b.d1,ULL(a.d2)*b.d2%md2);} Hdata operator+(const Hdata &a,int b){return Hdata(a.d1+b,a.d2+b);} Hdata operator+(const Hdata &a,const Hdata &b){return Hdata(a.d1+b.d1,a.d2+b.d2);} Hdata operator-(const Hdata &a,const Hdata &b){return Hdata(a.d1-b.d1,a.d2-b.d2);} bool operator==(const Hdata &a,const Hdata &b){return a.d1==b.d1&&a.d2==b.d2;} bool operator!=(const Hdata &a,const Hdata &b){return !(a==b);} bool operator<(const Hdata &a,const Hdata &b){return a.d1<b.d1||(a.d1==b.d1&&a.d2<b.d2);} #define N 1000000 const int X=131; Hdata pwx[N+100]; void init() { pwx[0]=Hdata(1,1); for(int i=1;i<=N;i++) pwx[i]=pwx[i-1]*X; } struct H { Hdata h;int sz; H():h(),sz(0){} H(const Hdata &a,int b):h(a),sz(b){} }; H operator+(const H &a,const H &b) { H ans;ans.sz=a.sz+b.sz; ans.h=a.h+b.h*pwx[a.sz]; return ans; } bool operator==(const H &a,const H &b) { return a.sz==b.sz&&a.h==b.h; } } using Hash::Hdata; using Hash::H; using Hash::X; using Hash::pwx;