题解: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;
}

浙公网安备 33010602011771号