【Hash 匹配】 兔子与兔子
传送门
题意
给定一个字符串\(S\),\(S\)仅包含小写英文字母,\(m\)个询问
每个询问包含两个区间\((l_{1},r_{1})\)和\((l_{2},r_{2})\),问字符串中这两个区间的字符是否相等
数据范围
\(1 \leq \text { length }(S), m \leq 1000000\)
题解
-
求初始每个下标的\(hash\)值
-
具体\(hash\)时候,假设有一个字符串\(abcde\),询问\((2,4)\)即\(bcd\)的\(hash\)值
-
整个字符串的\(hash\)值为\(12345\)
-
此处的\(l=2,r=4\) ,所以可以求\(hash(l-1) = 1,hash(r) = 1234\)
-
\(hash(l\sim r) =hash(r) - hash(l-1) \times P^{3} = 234\)
-
-
每次询问 \((l,r)\) 时通过相减求得即可
-
预处理数组\(p\),记录\(p\)的各个次方
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define close ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
const int N=1e6+10,P=131;
typedef unsigned long long ull;
char str[N];
int m;
ull h[N],p[N];
int main()
{
close;
cin>>str+1;
cin>>m;
p[0]=1;
int n=strlen(str+1);
rep(i,1,n+1)
{
h[i]=h[i-1]*P+(str[i]-'a'+1);
p[i]=p[i-1]*P;
}
while(m--)
{
int l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
if(h[r1] - (h[l1-1] * p[r1-l1+1]) == h[r2] - (h[l2-1] * p[r2-l2+1]))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
}

浙公网安备 33010602011771号