分析:
哈希字符串:”abcdef” P进制
把每一个字符按照顺序分配权重,设定P进制,使得h[i] = h[i] * P + str[i];
其中,str存放的字符的ASCII值,从前到后,字符的权重由大到小。
h[i]代表str[0]~str[i]的字符串的hash值。也就是前缀hash。(h[2] = “ab”的哈希值:$\cal{a * p^5 + b * p^4}$)
p[i]存放的是字符串中第i位的权重。$\cal{p[i] = p[i - 1] * P}$;
那么$\cal{h[r] - h[l - 1] * p[r - l + 1]}$ = 字符串r ~l 的哈希值。
例如:
代码
#include<stdio.h>
#include<iostream>
using namespace std;
/*当P进制为131 或者 13331的时候,几乎不可能发生冲突。*/
typedef unsigned long long ULL;
const int N = 100010, P = 131;
ULL h[N], p[N];
char str[N];
/*哈希字符串:"abcdef"
把每一个字符按照顺序分配权重,设定P进制,使得h[i] = h[i] * P + str[i];
其中,str存放的字符的ASCII值,从前到后,字符的权重由大到小。h[i]代表str[0]~str[i]的字符串的hash值。也就是前缀hash。(h[2] = "ab"的哈希值: a * p^5 + b * p^4)
p[i]存放的是字符串中第i位的权重。p[i] = p[i - 1] * n进制;
那么h[r] - h[l] * p[r - l + 1];把两个字符串的权重位对齐。
*/
ULL find(int l, int r)
{
return h[r] - h[l - 1] * p[r- l + 1];
}
int main()
{
int n, m;cin >> n >> m;
cin >> str + 1;
p[0] = 1;
/*i从1开始,因为h[]里面不能存0,否则“a” "aa" 都是0,两个不同的字符串无法分辨*/
for(int i = 1; i <= n; ++i)
{
p[i] = p[i - 1] * P;
/*自动把char型转int型。*/
h[i] = h[i - 1] * P + str[i];
}
while(m--)
{
int l1, r1, l2, r2;
cin >> l1 >> r1 >> l2 >> r2;
if(find(l1 , r1) == find(l2 , r2)) puts("Yes");
else puts("No");
}
return 0;