題目鏈接:https://ac.nowcoder.com/acm/contest/3781/D
思路:處理出前後綴最長迴文串,可以用manacher或者回文自動機
迴文自動機:
#pragma GCC optimize(2)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod ll(1e9+7)
#define pb push_back
#define eps 1e-6
#define lc d<<1
#define rc d<<1|1
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
const int N=2e5+8;
char s[N];
struct PAM{
struct node{
int len,fail,son[26],siz;
void init(int _len=0){
memset(son,0,sizeof(son));
fail=siz=0;
len=_len;
}
}tr[N];
char s[N];
int num,last,ds[N];
void init()
{
last=0;num=1;
tr[0].init();
tr[1].init(-1);
tr[0].fail=1;
REW(ds,0);
}
int getfail(int x,int n)
{
while(s[n-tr[x].len-1]!=s[n]) x=tr[x].fail;
return x;
}
void extend(int x,int n)
{
int cur=getfail(last,n);
int now=tr[cur].son[x];
if(!now)
{
now=++num;
tr[now].init();
ds[n]=tr[now].len=tr[cur].len+2;
tr[now].fail=tr[getfail(tr[cur].fail,n)].son[x];
tr[cur].son[x]=now;
}
if(n) ds[n]=max(ds[n],ds[n-1]);
tr[now].siz++;
last=now;
}
}A,B;
int main()
{
cin.tie(0);
cout.tie(0);
ss(s);
strcpy(A.s,s);
int ans=0;
int l=strlen(s);
A.init();B.init();
FOR(i,0,l-1) A.extend(A.s[i]-'a',i),B.s[i]=s[l-i-1];
FOR(i,0,l-1) B.extend(B.s[i]-'a',i);
FOR(i,0,l-2) ans=max(ans,A.ds[i]+B.ds[l-i-2]);
cout<<ans<<endl;
return 0;
}
manacher:
#pragma GCC optimize(2)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod ll(1e9+7)
#define pb push_back
#define eps 1e-6
#define lc d<<1
#define rc d<<1|1
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
const int N=2e5+8;
char a[N],b[N*2];
int d[N*2],dd[N],ddd[N];
int man()
{
int ll=strlen(a),l=0;
b[l++]='#';
FOR(i,0,ll-1) b[l++]=a[i],b[l++]='#';
int id=0,mx=0,qw,ans=0;
FOR(i,1,l-2)
{
if(mx>i) d[i]=min(d[2*id-i],mx-i);
else d[i]=1;
while(b[i-d[i]]==b[i+d[i]]&&i+d[i]<l) d[i]++;
if(i+d[i]>mx) mx=i+d[i],id=i;
dd[i/2+(d[i]-2)/2]=max(dd[i/2+(d[i]-2)/2],d[i]-1);
qw=i/2-(d[i]-2)/2;
if(!(i&1)) qw--;
ddd[qw]=max(ddd[qw],d[i]-1);
}
FOR(i,1,ll-1) ddd[i]=max(ddd[i],ddd[i-1]-2);
FOL(i,ll,0) ddd[i]=max(ddd[i],ddd[i+1]);
FOL(i,ll,0) dd[i]=max(dd[i],dd[i+1]-2);
FOR(i,1,ll-1) dd[i]=max(dd[i],dd[i-1]);
FOR(i,0,ll-2) ans=max(ans,dd[i]+ddd[i+1]);
return ans;
}
int main()
{
cin.tie(0);
cout.tie(0);
ss(a);
cout<<man()<<endl;
return 0;
}