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 }