题目大意
考虑一个只包含小写拉丁字母的字符串
s
。我们定义
现值”为
大出现值。
题解
回文树裸题,但是这里要注意一定要在最后统一推标记,否则全1串的时候一定会TLE。
这里附上一个写得很好的回文树讲解 回文树介绍(Palindromic Tree)
代码
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=int(3e5)+111;
struct Palind_Tree {
int len[maxn],next[maxn][26],fail[maxn],cnt[maxn];
int siz,suff;
bool add(char *s,int pos) {
int cur=suff, curlen=0;
int ch=s[pos]-'a';
while(true) {
curlen=len[cur];
if(pos-1-curlen>=0 && s[pos-1-curlen]==s[pos])
break;
cur=fail[cur];
}
if(next[cur][ch]) {
suff=next[cur][ch];
cnt[suff]++;
return false;
}
suff=++siz;
len[siz]=len[cur]+2;
next[cur][ch]=siz;
cnt[siz]=1;
if(len[siz]==1) {
fail[siz]=2;
return true;
}
cur=fail[cur];
while(true) {
curlen=len[cur];
if(pos-1-curlen>=0 && s[pos-1-curlen]==s[pos])
break;
cur=fail[cur];
}
fail[siz]=next[cur][ch];
return true;
}
void init() {
siz=2; suff=2;
len[1]=-1, fail[1]=1;
len[2]=0, fail[2]=1;
return;
}
long long get_res() {
for(int i=siz;i>=2;i--)
cnt[fail[i]]+=cnt[i];
long long res=0;
for(int i=3;i<=siz;i++)
res=max(res,1ll*len[i]*cnt[i]);
return res;
}
}Tree;
int n;
char s[maxn];
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif // ONLINE_JUDGE
Tree.init();
scanf("%s",&s);
n=strlen(s);
for(int i=0;i<n;i++)
Tree.add(s,i);
printf("%lld\n",Tree.get_res());
return 0;
}