字符串前缀哈希法将字符串前缀转为一个P进制的数存储,每个前缀都对应唯一一种字符串
h[N] 存放字符串的前缀值
p[N]存放各个位数的相应权值
步骤:
1.把字符串看作是P进制数 (P一般取131或者13331)
注:不能把字母 映射成0 ( 从1开始 )
2.预处理字符串所有的前缀hash值 h [ i ] = h [ i - 1 ] * P + str [ i ] ; str[i]这儿相当于str[i]*P^0
3.计算子串hash值 h [ r ] - h [ l - 1 ] * p [ r - l + 1 ] ;
模板题目链接:
https://www.acwing.com/problem/content/843/
#include<bits/stdc++.h>
using namespace std;
const int N=100010,P=131;
typedef unsigned long long ULL;
int n,m;
char str[N];
ULL p[N],h[N];/
ULL get(int l,int r){
return h[r]-h[l-1]*p[r-l+1];
}
int main(){
cin>>n>>m;
scanf("%s",str+1);
p[0]=1;
for(int i=1;i<=n;i++){
h[i] = h[i-1]*P+str[i];
p[i] = p[i-1] * P;
}
while(m--){
int l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
if(get(l1,r1)==get(l2,r2)) puts("Yes");
else puts("No");
}
return 0;
}
大佬,请教一下,那个str[i]加上为什么不乘上P啊?是因为直接加就可以得到计算出前i位哈希值的效果吗?
前面的h[i-1]相当于全部左移一位,给str [ i ]腾出位置, 其实加上的其实是str [ i ] * P^0 ,只不过P^0 等于1省略了