这个太不好用了
设哈希函数为多项式
[f(s) = sumlimits_{i=1}^n x^{n-i}*s[i]
]
这种方法称为字符串多项式哈希,优点是:方便递推、可以方便取出里面的子串。把[1..L-1]的前缀的多项式再乘以x^{R-L+1}次方,和[1..R]的前缀的多项式对应位置对齐,然后作差把前面多余的减掉。
struct Hashcode {
static const int MAXN = 1e5 + 10;
static ull MOD[2];
static ull BASE[2];
static ull PBASE[MAXN][2];
int len;
ull code[2];
static void init(int n) {
MOD[0] = 998244353, MOD[1] = 1004535809;
BASE[0] = 163, BASE[1] = 233;
PBASE[0][0] = 1, PBASE[0][1] = 1;
for (int i = 1; i <= n; ++i) {
PBASE[i][0] = PBASE[i - 1][0] * BASE[0] % MOD[0];
PBASE[i][1] = PBASE[i - 1][1] * BASE[1] % MOD[1];
}
}
static Hashcode concat(const Hashcode &x, const Hashcode &y) {
Hashcode res;
res.len = x.len + y.len;
res.code[0] = (x.code[0] * PBASE[y.len][0] + y.code[0]) % MOD[0];
res.code[1] = (x.code[1] * PBASE[y.len][1] + y.code[1]) % MOD[1];
return res;
}
ull getHashcode() {
return (code[0] << 32) | code[1];
}
};
假如要截取字符串的子串,则是要把对应R位置的[1,R]的多项式减去[1,L-1]的多项式乘以x^(R-L+1)次方。