哈希 Monitor QBXT Test Ⅱ T1

版权声明:未经本蒟蒻同意,请勿转载本蒻博客 https://blog.csdn.net/wddwjlss/article/details/83350702

题意:有 n n 个长度为 m m 的串,求在长度为 L L 的串中这 n n 个串中任意一个串出现的最早位置,如果 n n 个串都没有,输出 n o no ( m 20 , n 1 e 4 , L 1 e 5 ) (m≤20,n≤1e4,L≤1e5)

做法,因为每一个串长度都是一样的,考虑在最后的串内枚举每一段长度为 m m 的串,看它是否为 n n 个串中的一个。这里使用双哈希,首先先将 n n 串的哈希值算出,作为一个 p a i r pair 类型放入 m a p map 中,然后算出最后一个串的哈希前缀和,枚举比较输出即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#define ull unsigned long long
using namespace std;
const ull c1=19260817;
const ull c2=1e9+7;
map<pair<ull,ull>,int> mp;
int l,n,m;
char s[1001000],t[1001000];
ull mi1[1001000],mi2[1001000],h1[1001000],h2[1001000];
pair<ull,ull> gethash(int l,int r)
{
	ull x=h1[r]-h1[l-1]*mi1[r-l+1];
	ull y=h2[r]-h2[l-1]*mi2[r-l+1];
	return make_pair(x,y);
}
int main()
{
	bool flag=0;
	mi1[0]=mi2[0]=1;
	cin>>l>>n>>m;
	for(int i=1;i<=l;++i)
	{
		mi1[i]=mi1[i-1]*c1;
		mi2[i]=mi2[i-1]*c2;			
	}
	for(int i=1;i<=n;++i)
	{
		ull h1=0,h2=0;
		scanf("%s",s+1);
		for(int j=1;j<=m;++j)
		{
			h1=h1*c1+s[j]-'a'+1;
			h2=h2*c2+s[j]-'a'+1;
		}
		mp[make_pair(h1,h2)]=1;
	}
	scanf("%s",t+1);
	for(int i=1;i<=l;++i)
	{
		h1[i]=h1[i-1]*c1+t[i]-'a'+1;
		h2[i]=h2[i-1]*c2+t[i]-'a'+1;
	}
	for(int i=1;i<=l;++i)
	{
		int j=i+m-1;
		if(j>l)
			break;
		if(mp[gethash(i,j)])
		{
			flag=1;
			printf("%d",i);
			break;
		}
	}
	if(!flag)
		cout<<"no";
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wddwjlss/article/details/83350702