核心思想:用p(131或者13331)进制数储存字符串每一位数的hash值

L—R的哈希值 = h[R]-h[L-1]*PR-L+1
哈希值很大—>modQ(264)变小 == 用unsigned long long 存 (出界)
#include
using namespace std;
typedef unsigned long long ULL;
const int N=100010,P=131; //P用131 Q用2的64次方 冲突可忽略
int n,m;
char str[N];
ULL h[N],p[N];
ULL get(int l,int r){
return h[r] - h[l - 1]*p[r-l+1]; //推导的公式 求出l到r区间的哈希值
}
int main(){
scanf("%d%d%s" , &n,&m,str+1);
p[0]=1;
for(int i=1;i<=n;i++){
p[i] = p[i-1] *P; //保存p的多少次方
h[i] = h[i-1] *P+str[i]; //越往右越大
}
while(m--){
int l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
//如果哈希值相等 即字符串相同
if(get(l1,r1) == get(l2,r2)) printf("Yes\n");
else printf("No\n");
}
}
解惑:
**1.**h[i]为什么越来越大?不应该从左到右减小吗?
答:因为h[L]
