Acwing 841. 字符串哈希

地址:https://www.acwing.com/problem/content/843/

 

关于字符串哈希:

进制哈希。即把每个字符串按进制得出对应的数字。根据y总的模板,进制P取131可以很好地降低冲突概率

假设不出现冲突,那么每个子串,唯一对应一个P进制的哈希值。

先前缀处理一下所有前缀的哈希值。

那么对于[L,R],已知[1,R]和[1,L]的哈希值,需要求[L,R]的哈希值。

假设有:

ABCDEFGH

求[6,8]==FGH的哈希值

推导过程:

ABCDEFGH

ABCDE

它俩之间差三个字符(8-6+1)

那么ABCDE*P^(8-6+1),就是ABCDE000,

两者一减,就是FGH的哈希值了。

即:h[R]-h[L-1]*P^(R-L+1)

h[i]=h[i-1]*P+s[i]

h负责存前缀哈希

p[]负责存次放数

#include<cstdio>
#include<cstring>
#include<vector>
#include<set>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=1e5+10,maxn2=31*maxn;
const int P= 131;
ull h[maxn],p[maxn];
char s[maxn];
int n,m;
void init()
{
    for(int i=1;i<=n;i++)
    {
        p[i]=p[i-1]*P;
        h[i]=h[i-1]*P+s[i];
    }
}
ull check(int l,int r)
{
    return h[r]-h[l-1]*p[r-l+1];
}
int main()
{
    p[0]=1;    
    scanf("%d%d%s",&n,&m,s+1);
    init();
    while(m--)
    {
        int l1,r1,l2,r2;
        scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
        if(check(l1,r1)==check(l2,r2))
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }
}

 

posted @ 2020-11-11 20:02  liyexin  阅读(124)  评论(0编辑  收藏  举报