Oulipo

POJ

题意:多组数据,给定两个只含大写字母的字符串\(S1,S2\),求\(S1在\)S2$中出现了多少次?

分析:字符串哈希模板题,我写了双哈希,好像一个就够了.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define ull unsigned long long//无符号自然溢出,避免取模操作
using namespace std;
const int N=1e6+5;
char s1[N],s2[N];
int p1=1e9+7,p2=1e9+9;//选取的两个孪生质数
ull Base1[N],Base2[N],sum1[N],sum2[N];
int main(){
	Base1[0]=Base2[0]=1;
	for(int i=1;i<1000000;++i)Base1[i]=Base1[i-1]*p1;
	for(int i=1;i<1000000;++i)Base2[i]=Base2[i-1]*p2;//预处理
	int T;scanf("%d",&T);
	while(T--){
		scanf("%s%s",s1+1,s2+1);
		int n=strlen(s1+1),m=strlen(s2+1);
		for(int i=1;i<=m;++i){
			sum1[i]=sum1[i-1]*p1+(ull)(s2[i]-'A'+1);
			sum2[i]=sum2[i-1]*p2+(ull)(s2[i]-'A'+1);
		}//先计算主串的每个部分的哈希值
		ull s=0,ss=0;
		for(int i=1;i<=n;++i)s=s*p1+(ull)(s1[i]-'A'+1);
		for(int i=1;i<=n;++i)ss=ss*p2+(ull)(s1[i]-'A'+1);//在计算匹配串的哈希值
		int ans=0;
		for(int i=0;i<=m-n;++i){
			if(s==sum1[i+n]-sum1[i]*Base1[n]&&ss==sum2[i+n]-sum2[i]*Base2[n])//同时满足
				++ans;
		}
		printf("%d\n",ans);
	}
    return 0;
}

posted on 2019-09-28 14:34  PPXppx  阅读(219)  评论(0编辑  收藏  举报