【回文树】[APIO2014]Palindromes 标签: C++OIAPIO2014回文树 2017-07-15 17:25 6人阅读
题目链接
分析
用回文树,求出回文串的长度和出现的次数即可。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 300000
#define MAXC 26
using namespace std;
char s[MAXN+10];
int n;
long long ans;
inline void Read(int &x){
static char c;
while(c=getchar(),c!=EOF)
if(c>='0'&&c<='9'){
x=c-'0';
while(c=getchar(),c>='0'&&c<='9')
x=x*10+c-'0';
ungetc(c,stdin);
return;
}
}
void read(){
scanf("%s",s);
n=strlen(s);
}
namespace PalindromicTree{
int n,s[MAXN+10];
struct node{
int cnt,len;
node *ch[MAXC],*fail;
}tree[MAXN+10],*tcnt=tree,*last;
node *Get_fail(node *p){
while(s[n-p->len-1]!=s[n])
p=p->fail;
return p;
}
void init(node *p){
p->cnt=0;
for(int i=0;i<MAXC;i++)
p->ch[i]=tree;
}
void init(){
last=tree;
tcnt=tree;
init(tree);
init(++tcnt);
tcnt->len=-1;
tree->len=0;
tree->fail=tcnt;
tcnt->fail=tree;
s[0]=-1;
n=0;
}
void insert(char c){
s[++n]=c-='a';
node *cur=Get_fail(last);
if(cur->ch[c]==tree){
node *p=++tcnt;
init(p);
p->len=cur->len+2;
p->fail=Get_fail(cur->fail)->ch[c];
cur->ch[c]=p;
}
last=cur->ch[c];
last->cnt++;
}
void Get_cnt(){
for(node *p=tcnt;p>=tree;p--)
p->fail->cnt+=p->cnt;
}
}
void solve(){
for(int i=0;i<n;i++)
PalindromicTree::insert(s[i]);
PalindromicTree::Get_cnt();
using namespace PalindromicTree;
for(node *p=tcnt;p>=tree;p--)
ans=max(ans,1ll*p->cnt*p->len);
}
int main()
{
PalindromicTree::init();
read();
solve();
printf("%lld\n",ans);
}