【模板】回文树
作者:互联网
#include <stdio.h>
#include <string.h>
#include <bits/stl_algobase.h>
const int N = 524288;
struct PAM {
int cid[26];
int size, len;
int fail;
int cnt;
} pam[N];
#define sid(id,choice) pam[id].cid[choice]
#define size(id) pam[id].size
#define fail(id) pam[id].fail
#define len(id) pam[id].len
#define cnt(id) pam[id].cnt
int pam_tot, n;
char pattern[N];
int get(int x,int y) {
while(pattern[y] != pattern[y-len(x)-1])
x = fail(x);
return x;
}
void pam_work() {
n = strlen(pattern+1);
++pam_tot;
len(1) = -1;
fail(0) = 1;
pattern[0] = -1;
for(int i = 1, pass = 0;i <= n;++i) {
int sc = pattern[i]-'a';
int id = get(pass,i);
if(!sid(id,sc)) {
++pam_tot;
fail(pam_tot) = sid(get(fail(id),i),sc);
len(pam_tot) = len(id)+2;
sid(id,sc) = pam_tot;
size(pam_tot) = size(fail(pam_tot))+1;
}
pass = sid(id,sc);
++cnt(pass);
//size : 以该字符为结尾的回文串个数;
//len : 以该字符为结尾的最长回文串长度;
//fail : 指向以该字符为结尾的最长回文串的最长回文子串;
printf("%d %d %d %d\n",pass,size(pass),len(pass),fail(pass));
}
}
int query_tot() {
//pam_tot-1 即为本质不同回文串长度;
return pam_tot-1;
}
long long query_longest() {
long long res = 0;
for(int i = pam_tot;~i;--i) {
cnt(fail(i)) += cnt(i);
}
for(int i = 1;i <= pam_tot;++i)
res = std :: max(res,(long long)cnt(i)*len(i));
return res;
}
signed main() {
scanf("%s",pattern+1);
pam_work();
printf("%d\n",query_tot());
printf("%lld",query_longest());
}
标签:int,pattern,id,fail,define,pam,模板,回文 来源: https://www.cnblogs.com/bikuhiku/p/PAM.html