您的位置:首页 > 其它

[BZOJ3679][Apio2014]回文串

2016-04-28 15:36 447 查看

[Apio2014]回文串

Description

考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出

现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最

大出现值。

Input

输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。

Output

输出一个整数,为逝查回文子串的最大出现值。

Sample Input

【样例输入l】

abacaba

【样例输入2]

www

Sample Output

【样例输出l】

7

【样例输出2]

4

HINT

一个串是回文的,当且仅当它从左到右读和从右到左读完全一样。

在第一个样例中,回文子串有7个:a,b,c,aba,aca,bacab,abacaba,其中:

● a出现4次,其出现值为4:1:1=4

● b出现2次,其出现值为2:1:1=2

● c出现1次,其出现值为l:1:l=l

● aba出现2次,其出现值为2:1:3=6

● aca出现1次,其出现值为1=1:3=3

●bacab出现1次,其出现值为1:1:5=5

● abacaba出现1次,其出现值为1:1:7=7

故最大回文子串出现值为7。

【数据规模与评分】

数据满足1≤字符串长度≤300000。

Solution

回文自动机。

三大自动机已经集齐。

Code

#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = (l); i <= (r); i++)
#define per(i, r, l) for (int i = (r); i >= (l); i--)
#define REP(i, n) for (int i = 0; i < (n); i++)
#define PER(i, n) for (int i = (n)-1; i; i--)
#define MS(_) memset(_, 0, sizeof(_))
#define MP make_pair
#define PB push_back
typedef long long ll;
template<typename T> inline void read(T &x){
x = 0; T f = 1; char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
x *= f;
}
template<typename T> inline void ckmax(T &a, T b){ if (a < b) a = b; }
template<typename T> inline void ckmin(T &a, T b){ if (a > b) a = b; }

const int MaxN = 300010;
int n, fail[MaxN], nxt[MaxN][26], sz[MaxN];
ll len[MaxN], ans;
char str[MaxN];

struct PAM{
int cnt, last;
PAM(){ cnt = 1; fail[0] = fail[1] = 1; len[1] = -1; }
inline void ins(int c, int n){
int p = last;
for(; str[n-len[p]-1] != str
; p = fail[p]);
if (!nxt[p][c]){
int now = ++cnt, k = fail[p];
len[now] = len[p] + 2;
for (; str[n-len[k]-1] != str
; k = fail[k]);
fail[now] = nxt[k][c]; nxt[p][c] = now;
}
last = nxt[p][c]; sz[last]++;
}
inline void build(){
scanf("%s", str+1); n = strlen(str+1);
rep(i, 1, n) ins(str[i]-'a', i);
}
inline void solve(){
per(i, cnt, 1) sz[fail[i]] += sz[i], ckmax(ans, 1ll*sz[i]*len[i]);
}
}pam;
int main(){
pam.build();
pam.solve();
printf("%lld\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: