首先,假设一个字符串为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]
hash[4]=hash[3]
∗
X+s[4]=hash[2]
同理
hash[5]=s[1]
∗
X^4+s[2]
hash[6]=s[1]
∗
X^5+s[2]
假如l=1,r=3
gethash=hash[3]=s[1]
假如l=4,r=6
gethash=hash[6]-hash[3]
此时,由于s[1]==s[4],s[2]==s[5],s[3]==s[6],得到的哈希值是相同的。