题解:CF2010C1&CF2010C2

先用 KMP 求出 \(t\) 的最长公共前后缀长度,设 \(t\) 的最长公共前后缀长度为 \(k\),如果 \(2\cdot k\) 大于 \(t\) 的长度,那么 \(t\) 中就有错误,原串就是从 \(t\) 的最长公共前后缀。

证明:如果 \(2\cdot k\) 大于 \(t\) 的长度,那么就说明 \(t\) 的最长公共前后缀有相交的部分,那么相交处就为原串发生合并的地方,原串也就是从 \(t\) 的最长公共前后缀。

代码:

#include<bits/stdc++.h>
using namespace std;
string s;
int nxt[400000];
int main(){
	int n,i,j;
	cin>>s;
	n=s.length();
	nxt[0]=0;
	j=0;
	for(i=1;i<n;i++){
		while(j>0&&s[i]!=s[j])j=nxt[j-1];
		if(s[i]==s[j])j++;
		nxt[i]=j;
	}
	if(nxt[n-1]*2>n)
		cout<<"YES\n"<<s.substr(0,nxt[n-1])<<'\n';
	else cout<<"NO\n";
	return 0;
}
posted @ 2024-10-19 08:51  cly312  阅读(21)  评论(0)    收藏  举报