题解(我回来了)
2025-04-17 20:51:18
发布于:江苏
8阅读
0回复
0点赞
一眼kmp
分析:
其实想要求出答案
肯定要求出的所有子串在中出现的次数
这个好求
只需要在第二次kmp时,用一个数组记录每次的
(就代表长度为的子串,出现在这个位置)
然后直接求解
坑点:
列如:
(用不了\tt了)
统计数组(令为k):
1 2 3 4 5 4 5 4 5
下标
1 2 3 4 5 6 7 8 9
我们可以发现
再求时,需要再次记录
因为
可以分为
--------------
但正常计数会少算一个
所以每次都有给所有的值都算进去
时间:
#include <bits/stdc++.h>
#define int long long
using namespace std;
string s,ss;
int n,kmp[100010],k[100010];
int t[100010];
signed main(){
cin>>s>>ss>>n;
int m=ss.size();
int l=s.size();
int j=0;
ss=" "+ss;
s=" "+s;
for(int i=2;i<=m;i++){
while(j>0&&ss[i]!=ss[j+1])j=kmp[j];
if(ss[i]==ss[j+1])j++;
kmp[i]=j;
}
j=0;
for(int i=1;i<=l;i++){
while(j>0&&s[i]!=ss[j+1])j=kmp[j];
if(s[i]==ss[j+1])j++;
k[i]=j;
if(j==m)j=kmp[j];
}
// for(int i=1;i<=l;i++)cout<<k[i]<<' ';
//出现j=出现2次kmp[j]
for(int i=1;i<=l;i++){
int x=k[i];
while(x>0){
t[x]++;
x=kmp[x];
}
}
// for(int i=m;i>=1;i--)cout<<t[i]<<' ';
// cout<<endl;
for(int i=m;i>=1;i--){
if(t[i]>=n){
for(j=1;j<=i;j++)cout<<ss[j];
return 0;
}
// cout<<t[i]<<' ';
}
cout<<"IMPOSSIBLE";
return 0;
}
全部评论 1
求个点赞
1周前 来自 江苏
0
有帮助,赞一个