题解 | 寻寻觅觅寻不到
寻寻觅觅寻不到
https://ac.nowcoder.com/acm/contest/11178/B
【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(); }