期望时间复杂度 O(n + m),极限 \(O(nm)\)

首先输出若干行,每行一个整数,按从小到大的顺序输出 \(s_2\)​ 在 \(s_1\)​ 中出现的位置。
最后一行输出 \(\lvert s_2 \rvert\) 个整数,第 \(i\) 个整数表示 \(s_2\) 的长度为 \(i\) 的前缀的最长 \(border\) 长度。

#include <bits/stdc++.h>
using namespace std;
#define LL long long
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	string s, t;
	cin >> s >> t;
	int n = s.size(), m = t.size();
	vector <int> nxt(m + 1);
	s = '-' + s;
	t = '-' + t;
	for (int i = 2, j = 0; i <= m; i ++ ){
		while(j && t[i] != t[j + 1]) j = nxt[j];
		if (t[i] == t[j + 1]) j ++ ;
		nxt[i] = j;
	}
	for (int i = 1, j = 0; i <= n; i ++ ){
		while(j && s[i] != t[j + 1]) j = nxt[j];
		if (s[i] == t[j + 1]) j ++ ;
		if (j == m){
			cout << i - m + 1 << "\n";
			j = nxt[j];
		}
	}
	for (int i = 1; i <= m; i ++ )
		cout << nxt[i] << " \n"[i == m];
	return 0;
}

洛谷模板: https://www.luogu.com.cn/problem/P3375
Acwing模板:https://www.acwing.com/problem/content/833/

应用:
1.在字符串中查找子串
2.最小周期:字符串长度-整个字符串的border
3.最小循环节:区别于周期,当字符串长度 \(n \% (n - nxt[n]) == 0\) 时,等于最小周期,否则为 \(n\)

posted on 2022-03-02 13:07  Hamine  阅读(38)  评论(0编辑  收藏  举报