841. 字符串哈希
给定一个长度为 n 的字符串,再给定 m 个询问,每个询问包含四个整数 l1,r1,l2,r2,请你判断 [l1,r1] 和 [l2,r2] 这两个区间所包含的字符串子串是否完全相同。
字符串中只包含大小写英文字母和数字。
输入格式
第一行包含整数 n 和 m,表示字符串长度和询问次数。
第二行包含一个长度为 n 的字符串,字符串中只包含大小写英文字母和数字。
接下来 m 行,每行包含四个整数 l1,r1,l2,r2,表示一次询问所涉及的两个区间。
注意,字符串的位置从 1 开始编号。
输出格式
对于每个询问输出一个结果,如果两个字符串子串完全相同则输出 Yes,否则输出 No。
每个结果占一行。
数据范围
1≤n,m≤105
输入样例:
8 3
aabbaabb
1 3 5 7
1 3 6 8
1 2 1 2
输出样例:
Yes
No
Yes
理解:将字符串转化为p进制,然后用前缀和解决。原本的时间复杂度查找一次是O(N), 优化过后成了O(1)这是一种哈希方式,将字符串映射为p进制。如 ab 为 bp0 +ap1 ,更多的理解可以参考这个博客
python代码,python代码实际上过不了,得用c++,但是思路是一致的
import math
n,m = tuple(input().split())
n = int(n)
m = int(m)
s = list(input())
P = 131
Q = math.pow(2,64)
p = [0]*10010
p[0] = 1 # 对应的位
s1 = [0]*10010
def querry(x,y):
return s1[y] - s1[x-1]*p[y-x+1]
for i in range(len(s)):
p[i+1] = P*p[i]
s1[i+1] = ord(s[i])+s1[i]*P
for j in range(m):
x1,y1,x2,y2 = tuple(input().split())
x1 = int(x1)
y1 = int(y1)
x2 = int(x2)
y2 = int(y2)
if querry(x1,y1) == querry(x2,y2):
print('Yes')
else:
print('No')