【回文树】[APIO2014]Palindromes

题目链接

分析

用回文树,求出回文串的长度和出现的次数即可。

代码

#include
#include
#include
#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;ich[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;iusing 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);
}

你可能感兴趣的:(字符串)