常用的进制hash满足一些性质所有可以O(1) 查询子串或者减去某些位置的子串的hash值。
scanf("%d", &n);
scanf("%s", a+1);
p[0] = 1, h[0] = 0;
for(int i = 1; i <= n; i++){
h[i] = h[i-1]*base + a[i] - 'A';
p[i] = p[i-1]*base;
}
1.查询子串的hash值
比如ABACD的子串ACD的hash值为h[5]-h[3-1]*p[5-3+1]
inline unsigned long long get_hash(int l, int r)
{
return h[r] - h[l-1] * p[r-l+1];
}
证明:
2.查询子串再减去子串中的一个字符
unsigned long long get_s(int l, int r, int x)
//去掉x位置的字符得到的字符串的hash值
{
return get_hash(l, x-1) * p[r-x] + get_hash(x+1, r);
}
3.查询两个子串拼接的hash
unsigned long long get_s1_s2(int l1, int r1, int l2, int r2){
return get_hash(l1, r1) * p[r2-l2+1] + get_hash(l2, r2);
}