优雅的字符串哈希写法
如果有CE, 显卡看是不是NT写错模数
using ll = long long;
using ull = unsigned long long;
template<typename hst,hst B,hst M>
struct hash_s{
static hst phs[N];
int len ; hst val;
hash_s(int len_ = 0, hst val_= 0) : len(len_), val(val_){}
static void init(){
phs[0] = 1;
for(int i = 1; i < N; ++i) phs[i] = phs[i - 1] * B % M;
}
hash_s friend operator + (const hash_s& x,const hash_s& y){
return {x.len + y.len, (x.val * phs[y.len] + y.val) % M};
}
friend hash_s operator - (const hash_s& x, const hash_s& y){
return {x.len - y.len, ((x.val - y.val * phs[x.len - y.len]) % M + M) % M};
}
friend bool operator == (const hash_s& x, const hash_s& y){
return x.len == y.len && x.val == y.val;
}
};
template<typename hst,hst B,hst M>
hst hash_s<hst, B, M>::phs[N];
struct hash_m{
using _ht1 = hash_s<ll, 131, 998244353>;
using _ht2 = hash_s<ll, 1145141, 998244853>;
_ht1 h1;
_ht2 h2;
hash_m() = default;
hash_m(int len_, int val_){
h1 = {len_, val_};
h2 = {len_, val_};
}
hash_m(_ht1 h1_, _ht2 h2_){
h1 = h1_;
h2 = h2_;
}
static void init(){
_ht1::init();
_ht2::init();
}
hash_m friend operator +(const hash_m& x, const hash_m& y){
return {x.h1 + y.h1, x.h2 + y.h2};
}
hash_m friend operator -(const hash_m& x, const hash_m& y){
return {x.h1 - y.h1, x.h2 - y.h2};
}
bool friend operator ==(const hash_m& x, const hash_m& y){
return x.h1 == y.h1 && x.h2 == y.h2;
}
};