【Hash】自己對於一種字符串hash的證明(?)

首先,假設一個字符串爲s。
hash方式如下

#include<bits/stdc++.h>
#define fer(i,j,n) for(int i=j;i<=n;i++)
#define far(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
const int maxn=100010;
const int mod=1e9+7;
const int X=10003; //隨意取值
using namespace std;
/*----------------------------------------------------------------------------*/
inline int read()
{
    char ls;int x=0,sng=1;
    for(;ls<'0'||ls>'9';ls=getchar())if(ls=='-')sng=-1;
    for(;ls>='0'&&ls<='9';ls=getchar())x=x*10+ls-'0';
    return x*sng;
}
/*----------------------------------------------------------------------------*/
ll hash[maxn],len,pw[maxn];
char s[maxn];
int gethash(int l,int r)
{
    return (hash[r]-hash[l-1]*pw[r-l+1]%mod+mod)%mod;
}
int main()
{
    scanf("%s",s+1);
    len=strlen(s+1);
    fer(i,1,len)hash[i]=(hash[i-1]*X+s[i]-'a'+1)%mod;
    pw[0]=1;
    fer(i,1,len)pw[i]=pw[i-1]*X%mod;
    int n=read();
    fer(i,1,n)
    {
        int l=read(),r=read();
        cout<<gethash(l,r)<<endl;   
    }
}

這是一種運用了前綴與後綴很巧妙的hash方式,語言很難描述,直接看下面的這個例子。
假設s[]=abcabc
hash[1]=1(‘a’-‘a’+1)
hash[2]=s[1] X+s[2]
hash[3]=hash[2] X+s[3]=s[1] X^2+s[2] X+s[3]
hash[4]=hash[3] X+s[4]=hash[2] X^2+s[3] X+s[4]=s[1] X^3+s[2] X^2+s[3] X+s[4]
同理
hash[5]=s[1] X^4+s[2] X^3+s[3] X^2+s[4] X+s[5]
hash[6]=s[1] X^5+s[2] X^4+s[3] X^3+s[4] X^2+s[5] X+s[6]
假如l=1,r=3
gethash=hash[3]=s[1] X^2+s[2] X+s[3]
假如l=4,r=6
gethash=hash[6]-hash[3] X^3=s[1] X^5+s[2] X^4+s[3] X^3+s[4] X^2+s[5] X+s[6]-s[1] X^5+s[2] X^4+s[3] X^3=s[4] X^2+s[5] X+s[6]
此時,由於s[1]==s[4],s[2]==s[5],s[3]==s[6],得到的哈希值是相同的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章