ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【Luogu P3426】[POI2005]SZA-Template

2021-11-20 01:00:18  阅读:195  来源: 互联网

标签:nxt POI2005 Luogu ll SZA && mathrm border getchar


链接:

洛谷

题目大意:

给定一个字符串 \(s\),找到最小的 \(t\) 使得 \(t\) 匹配的位置能覆盖 \(s\)。

思路:

\(t\) 一定是 \(s\) 的一个前后缀(\(s\) 也算),考虑 DP。设 \(f_i\) 表示前缀 \(i\) 的答案,那么 \(f_i\) 要么是 \(i\),要么是 \(f_{\mathrm{border}(i)}\)。那么如果是 \(f_{\mathrm{border}(i)}\),那么某个 \(f_j=f_{\mathrm{border}(i)}\) 一定在 \([i-\mathrm{border}(i),i]\) 内。

代码:

const int N = 5e5 + 10;

inline ll Read() {
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

char s[N];
int nxt[N], f[N], g[N];;

int main() {
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	scanf ("%s", s + 1);
	int n = strlen (s + 1);
	for (int i = 2, j = 0; i <= n; i++) {
		while (j && s[i] != s[j + 1]) j = nxt[j];
		if (s[i] == s[j + 1]) j++;
		nxt[i] = j;
	}
	for (int i = 1; i <= n; i++) {
		f[i] = i;
		if (g[f[nxt[i]]] >= i - nxt[i]) f[i] = f[nxt[i]];
		g[f[i]] = i;
	}
	printf ("%d\n", f[n]);
	return 0;
}

标签:nxt,POI2005,Luogu,ll,SZA,&&,mathrm,border,getchar
来源: https://www.cnblogs.com/GJY-JURUO/p/15579851.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有