1.字符串哈希

 

方法概述:

  • 选取两个合适的互质常数b,h(b<h),把字符串看成b进制数,算出这个数模h
  • 设H(C,k)为前k个字符构成的字符串的哈希值,则:H(C',k)=H(C,k+n)-H(C,k)*bn

                                                                                      --------具体见《信息学奥赛一本通提高篇》

 

关于正确性:可以用双哈希降低出现相同哈希值的概率 取109+7和109+9,就几乎不可能发生冲突,因为它们是孪生质数

 

板子题:   poj3461

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define R register
 5 #define go(i,a,b) for(R int i=a;i<=b;i++)
 6 #define il inline
 7 #define ll unsigned long long//记得是unsigned long long
 8 #define M 1000001
 9 using namespace std;
10 il int rd()
11 {
12     int x=0,y=1;char c=getchar();
13     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
14     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
15     return x*y;
16 }
17 int T,l1,l2,ans,b=29;
18 char s1[M],s2[M],tmp[M];
19 ll dat,hash[M],p[M];
20 int main()
21 {
22     T=rd();
23     p[0]=1;go(i,1,1000000) p[i]=p[i-1]*b;
24     while(T--)
25     {
26         scanf("%s%s",s1+1,s2+1);ans=0;
27         l1=strlen(s1+1);l2=strlen(s2+1);
28         hash[0]=1;
29         go(i,1,l2) hash[i]=hash[i-1]*b+(ll)(s2[i]-'A'+1);
30         dat=0;
31         go(i,1,l1) dat=dat*b+(ll)(s1[i]-'A'+1);
32         go(i,0,l2-l1)
33         if(dat==hash[i+l1]-hash[i]*p[l1])ans++;
34         printf("%d\n",ans);
35     }
36     return 0;
37 }
View Code

相关文章: