题解(我回来了)
2025-04-17 20:51:18
发布于:江苏
15阅读
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
求个点赞
2025-04-17 来自 江苏
0

有帮助,赞一个