考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出
现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最
大出现值。
标签:
考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出
现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最
大出现值。
输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。
输出一个整数,为逝查回文子串的最大出现值。
#include <iostream> #include <string.h> #include <algorithm> #include <math.h> #include <stdio.h> #include <stdlib.h> using namespace std; typedef long long int LL; const int maxn=3e5+10; char str[maxn]; struct Tree { int next[maxn][26]; int fail[maxn]; int num[maxn]; LL cnt[maxn]; int len[maxn]; int s[maxn]; int p; int n; int last; int new_node(int x) { memset(next[p],0,sizeof(next[p])); cnt[p]=0; num[p]=0; len[p]=x; return p++; } void init() { p=0; new_node(0); new_node(-1); last=0;n=0; s[0]=-1; fail[0]=1; } int get_fail(int x) { while(s[n-len[x]-1]!=s[n]) x=fail[x]; return x; } int add(int x) { x-='a'; s[++n]=x; int cur=get_fail(last); if(!(last=next[cur][x])) { int now=new_node(len[cur]+2); fail[now]=next[get_fail(fail[cur])][x]; next[cur][x]=now; num[now]=num[fail[now]]+1; last=now; } cnt[last]++; } void count() { for(int i=p-1;i>=0;i--) cnt[fail[i]]+=cnt[i]; } }tree; int main() { while(scanf("%s",str)!=EOF) { int len=strlen(str); tree.init(); for(int i=0;i<len;i++) tree.add(str[i]); tree.count(); LL ans=0; for(int i=2;i<tree.p;i++) ans=max(ans,(LL)tree.cnt[i]*tree.len[i]); printf("%lld\n",ans); } return 0; }
标签:
原文地址:http://blog.csdn.net/dacc123/article/details/51360390