哈希
mod的数一般取一个质数
离2的整数次幂尽量远
大于10万的第一个质数,1e5+3;
1.原子操作
1.1.插入
1.1.1.开放寻址法
h[find(x)]=x;
1.1.2.拉链法
void insert(int x)
{
int k=(x%N+N)%N;
e[idx]=x;
ne[idx]=h[k];
h[k]=idx++;
}
1.2.查询
1.2.1.开放寻址法
void find(int x){
int t = (x%N+N)%N;
while(h[t]!=null&&h[t]!=x)
{
t++;
if(t==N) t=0;
}
return t;
}
1.2.3.拉链法
bool find(int x)
{
int k = (x%N+N)%N;
for(int i=h[k];i!=-1;i=ne[i])
if(e[i]==x)
return true;
return false;
}
2.字符串哈希
P一般取131
首先核心在于,将一段字符串映射为一个数
abcde注意字符串是从左往右看的,但是从右往左依次是高位。
那么求de这个字符串表示时候,l=4,r=5
h [ r ] = h [ 5 ] h[r]=h[5] h[r]=h[5],代表 a b c d e abcde abcde代表 a ∗ q 5 + b ∗ q 4 + c ∗ q 3 + d ∗ q 2 + e ∗ q 1 a*q^5+b*q^4+c*q^3+d*q^2+e*q^1 a∗q5+b∗q4+c∗q3+d∗q2+e∗q1
h [ l − 1 ] = h [ 3 ] h[l-1]=h[3] h[l−1]=h[3]代表 a b c abc abc代表 a ∗ q 3 + b ∗ q 2 + c ∗ q 1 a*q^3+b*q^2+c*q^1 a∗q3+b∗q2+c∗q1
下面是一个小技巧,使用ULL,相当于队 2 64 2^{64} 264取模
ULL get(int l,int r)
{
return h[r]-h[l-1]*q[r-l+1];
}
ULL h[N],p[N];
int main(){
scanf("%d%d",&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;
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
if(get(l1,r1)==get(l2,r2)) puts("Yes");
else puts("No");
}
return 0;
}