Prefix-Suffix Palindrome (Hard version) (补) (Manacher)
题目:
给你一个字符串,让你找一个最大回文串,这个回文串由该字符串的前缀和后缀一起组成
思路:
先处理字符串的两端直到两端不匹配为止,然后对中间的字符串跑一遍Manacher算法,然后
找出起始点为1或终止点为s.size()的最大回文串输出(这样才能保证满足前缀或后缀的条件),再分别输出即可
链接:
https://codeforces.com/contest/1326/problem/D2
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=2e6+5; const int INF=0x3f3f3f3f3f3f3f; const int mod=998244353; string s,s1; int len[MAXN]; void init(int l,int r) { s+='$';s+='#'; for(int i=l;i<=r;i++) { s+=s1[i]; s+='#'; } } int start,max_r; //start表示起始点,max_r表示回文串的最长半径 void manacher() { int mx=0,id=0; for(int i=1;i<s.size();i++) { len[i]=mx>i?min(len[2*id-i],mx-i):1; while(s[i+len[i]]==s[i-len[i]]) len[i]++; if(i+len[i]>mx) { mx=i+len[i];id=i; } if(i==len[i]) { if(max_r<len[i]) start=1,max_r=len[i]; } else if(i+len[i]==s.size()) { if(max_r<len[i]) start=i-len[i]+1,max_r=len[i]; } } } int main() { ios::sync_with_stdio(false);cin.tie(0); int t;cin>>t; while(t--) { s="",start=0,max_r=0; cin>>s1; int len=s1.size(); int l=0,r=len-1; while(s1[l]==s1[r]) r--,l++; //cout<<l<<" "<<r<<endl; if(l>r) cout<<s1<<endl; else { init(l,r); for(int i=0;i<l;i++) cout<<s1[i]; manacher(); for(int i=start;i<=start+(max_r-1)*2;i++) { if(s[i]=='#') continue; cout<<s[i]; } for(int i=r+1;i<s1.size();i++) cout<<s1[i]; cout<<endl; } } }