【B.寻寻觅觅寻不到】 题解
看有位大佬写的题解挺长的,感觉这题目考察点就一个:区间字符串哈希
对于区间的字符串哈希值,公式如下:
题目也就是从字串中取出长度为 的子串,将其放在主串的后面构成新的串,看是否和文本串匹配,这里指
串。
所以就是拼接的问题了,由于我们取了长度为 的子串,那么整个主串就分成三分,分别是
,对应的我们分别用
表示。那么组合成的新的主串的哈希值我们可以比着区间的去做:
其中 表示进制,
表示区间长度。实现的思路主要就是往前进位嘛。
看数据范围非常友好,就直接暴力枚举区间,判断时否和 的哈希值相同就好了。
清奇的码风
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <cstring>
#define int long long
using namespace std;
const int B=4*1e5+10;
const int base=131;
const int mod=1e9+7;
int T;
int ha[B];
int haa[B];
int jc[B];
char a[B],c[B];
int read() {int x;scanf("%lld",&x);return x;}
int get(int l,int r)
{
return (ha[r]%mod-ha[l-1]%mod*jc[r-l+1]%mod+mod)%mod;
}
void solve()
{
cin>>a+1;
cin>>c+1;
int k=read();
int la=strlen(a+1); ha[0]=0;
int lc=strlen(c+1);
int sum=0;
for (int i=1;i<=la;i++) ha[i]=(ha[i-1]*base%mod+a[i]%mod+mod)%mod;
for (int i=1;i<=lc;i++) sum=(sum%mod*base%mod+c[i]%mod+mod)%mod;
for (int l=1;l+k-1<=la;l++)
{
int s1=get(1,l-1);
int s2=get(l,l+k-1);
int s3=get(l+k,la);
int ans=(s1%mod*jc[la-l+1]%mod+s3%mod*jc[k]%mod+s2)%mod;
if (ans==sum) {printf("YES\n");return;}
}
printf("NO\n");return;
}
signed main()
{
jc[0]=1;
for (int i=1;i<=B-2;i++) jc[i]=(jc[i-1]%mod*base%mod)%mod;
T=read();
while (T--) solve();
}

京公网安备 11010502036488号