Loading

字符串 Hash 兔子与兔子

字符串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");
    }
}

 

posted @ 2020-07-12 21:04  MQFLLY  阅读(187)  评论(0编辑  收藏  举报