bzoj 3676: [Apio2014]回文串 回文自动机
题目:
Description
考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最 大出现值。
Input
输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。
Output
输出一个整数,为逝查回文子串的最大出现值。
题解:
回文自动机裸题
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 300010;
struct Node{
int nx[26];
int len,fail,siz,num;
}T[maxn];
int last,nodecnt,str[maxn],len;
inline void init(){
last = nodecnt = 0;
T[++nodecnt].len = -1;
str[len=0] = -1;
T[0].fail = 1;
}
inline void insert(char cha){
int c = cha - 'a',p,cur,x;str[++len] = c;
for(p = last;str[len - T[p].len - 1] != str[len];p = T[p].fail);
if(T[p].nx[c] == 0){
T[cur = ++ nodecnt].len = T[p].len + 2;
for(x = T[p].fail;str[len - T[x].len - 1] != str[len];x = T[x].fail);
T[cur].fail = T[x].nx[c];T[p].nx[c] = cur;T[cur].num = T[T[cur].fail].num+1;
}T[last = T[p].nx[c]].siz ++ ;
}
char s[maxn];
int main(){
init();scanf("%s",s);int len = strlen(s);
for(int i=0;i<len;++i) insert(s[i]);
ll ans = 0;
for(int i = nodecnt;i>=2;--i){
if(T[i].fail) T[T[i].fail].siz += T[i].siz;
ans = max(ans,1LL*T[i].siz*T[i].len);
}printf("%lld\n",ans);
getchar();getchar();
return 0;
}
人就像命运下的蝼蚁,谁也无法操控自己的人生.