哈希

质数:

超大(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;
原文地址:https://www.cnblogs.com/hehe54321/p/9021950.html