字符串Hash可以把一个长度任意的字符串映射成一个非负整数,并且其冲突概率几乎为0
取一固定值P,把字符串看作P进制数,并分配一个大于0的值,代表每种字符。一般来说,分配的数都远小于P。例如 a = 1, b=2 , z=26
取一个固定值M,求出该P进制对M的余数,作为Hash值。
一般来说,P取131或者13331,M取2^64,即直接用unsigned long long 存储这个哈希值。
H(S + c) = (H(S)*P + value[c]) %M
乘P相当于左移运算。
H(T) = (H( S + T) - H(S) * p^(lengT) ) %M ,相当于将S补0到位数相同再相减来得到T
给出一个字符串 S , length(S) <= 1e6 .
有Q个询问,每个询问给出两个区间,问两区间的字符串是否相同。
思路:可以利用Hash O1查找
char s[maxn]; unsigned long long f[maxn], p[maxn]; int main() { scanf("%s", s + 1); int n = strlen(s) + 1; int q; scanf("%d", &q); p[0] = 1; // p ^ 0 = 1 for (int i = 1; i <= n; i++) { f[i] = f[i - 1] * 131 + (s[i] - 'a' + 1); p[i] = p[i - 1] * 131; } while (q--) { int l1, r1, l2, r2; scanf("%d%d%d%d", &l1, &r1, &l2, &r2); if (f[r1] - f[l1 - 1] * p[r1 - l1 + 1] == f[r2] - f[l2 - 1] * p[r2 - l2 + 1]) puts("YES"); else puts("NO"); } }