其他分享
首页 > 其他分享> > CodeForces 432D Prefixes and Suffixes

CodeForces 432D Prefixes and Suffixes

作者:互联网

洛谷传送门

CF 传送门

思路

首先求出原串的 \(\mathbf{Z}\) 函数数组 \(nxt\),那么长度为 \(n - i + 1\) 的前后缀满足要求当且仅当 \(i + nxt_i - 1 = n\)。

显然长度为 \(i\) 的前缀的出现次数为满足 \(nxt_j \ge i\) 的 \(j\) 的个数,差分 + 后缀和维护即可。

时间复杂度 \(O(|s|)\)。

代码

code
/*

p_b_p_b txdy
AThousandMoon txdy
AThousandSuns txdy
hxy txdy

*/

#include <bits/stdc++.h>
#define pb push_back
#define fst first
#define scd second

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 100100;

int n, nxt[maxn], f[maxn];
char s[maxn];

void solve() {
	scanf("%s", s + 1);
	n = strlen(s + 1);
	nxt[1] = n;
	for (int i = 2, l = 0, r = 0; i <= n; ++i) {
		nxt[i] = (i > r) ? 0 : min(nxt[i - l + 1], r - i + 1);
		while (s[nxt[i] + 1] == s[nxt[i] + i]) {
			++nxt[i];
		}
		if (i + nxt[i] - 1 > r) {
			l = i;
			r = i + nxt[i] - 1;
		}
	}
	for (int i = 1; i <= n; ++i) {
		++f[nxt[i]];
	}
	for (int i = n; i; --i) {
		f[i] += f[i + 1];
	}
	vector<pii> ans;
	for (int i = 1; i <= n; ++i) {
		if (i + nxt[i] - 1 == n) {
			ans.pb(make_pair(nxt[i], f[nxt[i]]));
		}
	}
	sort(ans.begin(), ans.end());
	printf("%d\n", (int)ans.size());
	for (pii p : ans) {
		printf("%d %d\n", p.fst, p.scd);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:nxt,txdy,int,CodeForces,Prefixes,传送门,maxn,define,Suffixes
来源: https://www.cnblogs.com/zltzlt-blog/p/16399124.html