D2. Prefix-Suffix Palindrome (Hard version)
题意
要求从s中找到一个t
使得 t的长度不超过s
t是回文串
存在s的前缀a和后缀b a+b=t
|s|<1e5
题解
先从两边取对称的前后缀,之后再取余下字符串较长的回文前缀或后缀用马拉车实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| # include<bits/stdc++.h>
# define endl "\n"
using namespace std; typedef long long ll;
inline string makestr(string str){ string t="#"; for(int i=0;i<str.size();i++)t+=str[i],t+='#'; return t; } string malacher(string str){ string t=makestr(str); vector<int>p(t.size(),0); int mx=0,id=0,ilenth=0,icenter=0; for(int i=1;i<t.size();i++){ p[i]=i<mx?min(p[2*id-i],mx-i):1; while(t[i-p[i]]==t[i+p[i]])p[i]++; if(p[i]+i>mx){ mx=p[i]+i; id=i; } if(p[i]>ilenth){ ilenth=p[i]; icenter=i; } } int Maxlen=0; for(int i=0;i<t.size();i++)if(p[i]==i+1)Maxlen=p[i]; return str.substr(0,Maxlen-1); } int main(){ int t;cin>>t; while(t--){ string s;cin>>s; int l=0,r=s.size()-1; while(s[l]==s[r]&&l<r)l++,r--; string s1=s.substr(l,r-l+1); string s2=s1;reverse(s1.begin(),s1.end()); s1=malacher(s1); s2=malacher(s2); cout<<s.substr(0,l)<<(s1.size()>s2.size()?s1:s2)<<s.substr(r+1)<<endl; } }
|