字符串哈希
-
核心思想:用p(131或者13331)进制数储存字符串每一位数的hash值
-
L—R的哈希值 = h[R]-h[L-1]*PR-L+1
-
哈希值很大—>modQ(264)变小 == 用unsigned long long 存 (出界)
-
#include<iostream> 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]<h[R] 求哈希值时 h[L]*pn才能跟h[R]在同一个位次相减
-