监听的宇宙电波可以抽象成1个长度为 L 的小写字母组成的字符串。
同时在三体⼈总结出来了 n 段敏感电波的样⼦,每段敏感电波的长度 都是 m。 现在请你实现⼀个程序,求出在这长度为 L 的小写字母组成的字符串 中某个敏感电波第1次出现的位置(位置从 1 开始计数)。 如果从头到尾,没有任何敏感电波出现,输出”no”(不带双引号)。
思路 hash
- 把L拆分成每m一段,在n里二分这个值
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
int read()
{
char ch=' ';
int f=1;int x=0;
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';ch=getchar();
}
return x*f;
}
const int N=1e4+100;
const int M=1e5+100;
const int base=27;
const int p=1e9+7;
ull bit[100];
ull hsum[N];
char a[N][100];
char s[M];
ull ssum[M];
ull geth(int l,int r)
{
return (ssum[r]-ssum[l-1]*bit[r-l+1]%p+p)%p;
}
int main()
{
int l,n,m;
l=read(),n=read(),m=read();
bit[0]=1;
int i,j;
for(i=1;i<=m;i++)
{
bit[i]=bit[i-1]*base%p;
}
for(i=1;i<=n;i++)
{
scanf("%s",a[i]+1);
for(j=1;j<=m;j++)
{
hsum[i]=(hsum[i]*base%p+a[i][j]-'a')%p;
}
}
sort(hsum+1,hsum+1+n);
scanf("%s",s+1);
for(i=1;i<=l;i++)
{
ssum[i]=(ssum[i-1]*base%p+s[i]-'a')%p;
}
for(i=1;i+m-1<=l;i++)
{
ull x=geth(i,i+m-1);
int pos=lower_bound(hsum+1,hsum+1+n,x)-hsum;
if(hsum[pos]==x)
{
cout<<i<<endl;
return 0;
}
}
cout<<"no"<<endl;
return 0;
}