哈希 Monitor QBXT Test Ⅱ T1

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

做法,因为每一个串长度都是一样的,考虑在最后的串内枚举每一段长度为 m m m的串,看它是否为 n n n个串中的一个。这里使用双哈希,首先先将 n n n串的哈希值算出,作为一个 p a i r pair pair类型放入 m a p map 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值