# APIO 2014 回文串（Manacher+后缀自动机+倍增）

## 题意

https://www.lydsy.com/JudgeOnline/problem.php?id=3676

## 代码

#include<bits/stdc++.h>
#define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
#define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
template<typename T,typename _T>inline bool chk_min(T &x,const _T y){return y<x?x=y,1:0;}
template<typename T,typename _T>inline bool chk_max(T &x,const _T y){return x<y?x=y,1:0;}
typedef long long ll;
const int N=(int)6e5+5;
template<const int maxn,const int maxm,typename T>struct Linked_list
{
#define EOR(i,G,u) for(int i=G.head[u];~i;i=G.nxt[i])
};
int *fa[N];
int las,tot;
char str[N];int idx[N];
char mnc[N];int p[N];
int n;
ll ans;

void init()
{
las=tot=1;
FOR(i,0,25)ch[1][i]=0;
}
void extend(char c)
{
int p=las,cur=++tot;
FOR(i,0,25)ch[cur][i]=0;
len[cur]=len[p]+1;
sz[cur]=1;
else
{
int q=ch[p][c-'a'];
if(len[p]+1==len[q])
else
{
int clone=++tot;
FOR(i,0,25)ch[clone][i]=ch[q][i];
len[clone]=len[p]+1;
sz[clone]=0;
}
}
las=cur;
}
void dfs(int u)
{
EOR(i,G,u)
{
int v=G[i];
dfs(v);
sz[u]+=sz[v];
}
}

void solve(int l,int r)
{
int p=idx[r];
DOR(i,20,0)if(len[fa[p][i]]>=r-l+1)
p=fa[p][i];
chk_max(ans,1ll*sz[p]*(r-l+1));
}

void Manacher(char *str,int len)
{
int n=1;
mnc[1]='#';
FOR(i,1,len)mnc[++n]=str[i],mnc[++n]='#';
int mr=0,pos;
FOR(i,1,n)
{
if(i<=mr)p[i]=std::min(p[(pos<<1)-i],mr-i+1);
else p[i]=1;
while(i-p[i]>=1&&i+p[i]<=n&&mnc[i-p[i]]==mnc[i+p[i]])
{
p[i]++;
if(mnc[i-p[i]+1]=='#')solve((i-p[i]+1+1)>>1,(i+p[i]-1-1)>>1);
}
if(chk_max(mr,i+p[i]-1))pos=i;
}
}

int main()
{
scanf("%s",str+1);
n=strlen(str+1);
init();
FOR(i,1,n)extend(str[i]),idx[i]=las;