我直接在一个串上面二分找最远的回文部分
然后枚举所有的回文部分在另一个串上面匹配
(目测复杂度 O(n2) 结果给过去了……)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define reg register
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
#define ull unsigned long long
const int N=1e5+10;
const ull base=13331;
ull p[N];
struct node{
ull h1[N],h2[N];
char s[N];
int len,lpos[N],rpos[N];
inline ull get1(int l,int r){return h1[r]-h1[l-1]*p[r-l+1];}
inline ull get2(int l,int r){return h2[l]-h2[r+1]*p[r-l+1];}
inline void prework(char *t)
{
for(reg int i=1;i<=len;++i) h1[i]=h1[i-1]*base+s[i];
for(reg int i=len;i>=1;--i) h2[i]=h2[i+1]*base+s[i];
return ;
}
inline pair<int,int> calc1(int id)
{
int l=1,r=len,ans=1;
while(l<=r)
{
int mid=(l+r)>>1;
if(id-mid+1<1||id+mid-1>len){r=mid-1; continue;}
if(get1(id,id+mid-1)==get2(id-mid+1,id)) l=mid+1,ans=mid;
else r=mid-1;
}return make_pair(id-ans+1,id+ans-1);
}
inline pair<int,int> calc2(int L,int R)
{
int l=1,r=len,ans=1;
while(l<=r)
{
int mid=(l+r)>>1;
if(L-mid+1<1||R+mid-1>len){r=mid-1;}
if(get2(L-mid+1,L)==get1(R,R+mid-1)) l=mid+1,ans=mid;
else r=mid-1;
}
return make_pair(L-ans+1,R+ans-1);
}
}s1,s2;
int mx=0;
char s[N];
inline bool check(int st1,int st2)//s1 to the left,s2 to th right
{
int ans=0,l=1,r=s1.len;
while(l<=r)
{
int mid=(l+r)>>1;
if(st1-mid+1<1||st2+mid-1>s1.len){r=mid-1; continue;}
if(s1.get2(st1-mid+1,st1)==s2.get1(st2,st2+mid-1)) l=mid+1,ans=mid;
else r=mid-1;
}
if(ans) mx=max(mx,ans*2+st2-st1);
return ans;
}
signed main()
{
p[0]=1; for(reg int i=1;i<N;++i) p[i]=p[i-1]*base;
s1.len=s2.len=read();
scanf("%s",s1.s+1); s1.prework(s);
scanf("%s",s2.s+1); s2.prework(s);
for(reg int i=1;i<=s1.len;++i)
{
pair<int,int> tmp=s1.calc1(i);
int lpos=tmp.first,rpos=tmp.second;
for(reg int j=lpos;j<=i;++j) if(check(j-1,2*i-j)) break;
}
for(reg int i=1;i<=s1.len;++i)
{
pair<int,int> tmp=s2.calc1(i);
int lpos=tmp.first,rpos=tmp.second;
for(reg int j=lpos;j<=i;++j) if(check(j,2*i-j+1)) break;
}
for(reg int i=1;i<s1.len;++i)
{
//偶回文,中心是 (i,i+1)
if(s1.s[i]!=s1.s[i+1]) continue;
pair<int,int> tmp=s1.calc2(i,i+1);
int lpos=tmp.first,rpos=tmp.second;
for(reg int j=lpos;j<=i;++j) if(check(j-1,2*i+1-j)) break;
}
for(reg int i=1;i<s1.len;++i)
{
if(s2.s[i]!=s2.s[i+1]) continue;
pair<int,int> tmp=s2.calc2(i,i+1);
int lpos=tmp.first,rpos=tmp.second;
for(reg int j=lpos;j<=i;++j) if(check(j,2*i+2-j)) break;
}
//上下中心
for(reg int i=1;i<=s1.len;++i)
{
if(s1.s[i]!=s2.s[i]) continue;
int ans=1,l=1,r=s1.len;
while(l<=r)
{
int mid=(l+r)>>1;
if(s1.get2(i-mid+1,i)==s2.get1(i+1,i+mid-1)) ans=mid,l=mid+1;
else r=mid-1;
}mx=max(mx,ans<<1);
} cout<<mx<<endl;
return 0;
}
}
signed main(){return yspm::main();}