1. 程式人生 > >bzoj3676 [Apio2014]回文串

bzoj3676 [Apio2014]回文串

long 次數 滿足 回文 -- color stream algorithm sin

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。

正解:回文自動機。

集訓隊論文裏出現了回文自動機這種高級東西,於是學了一下,其實挺簡單的。。

這題就是直接構造出回文自動機,統計每個回文串出現的次數,取個最值就行了。。沒什麽好說的。。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <cmath>
 7 #define N (300010)
 8 #define il inline
 9 #define RG register
10 #define
ll long long 11 12 using namespace std; 13 14 int ch[N][26],f[N],v[N],l[N],n,la,tot; 15 char s[N]; 16 ll ans; 17 18 il void add(RG int c,RG int n){ 19 RG int x=la; while (s[n-l[x]-1]!=s[n]) x=f[x]; 20 if (!ch[x][c]){ 21 RG int v=++tot,k=f[x]; l[v]=l[x]+2; 22 while (s[n-l[k]-1]!=s[n]) k=f[k]; 23 f[v]=ch[k][c],ch[x][c]=v; 24 } 25 v[la=ch[x][c]]++; return; 26 } 27 28 il void work(){ 29 scanf("%s",s+1),n=strlen(s+1),l[++tot]=-1,f[0]=1; 30 for (RG int i=1;i<=n;++i) add(s[i]-97,i); 31 for (RG int i=tot;i;--i) ans=max(ans,1LL*l[i]*v[i]),v[f[i]]+=v[i]; 32 printf("%lld\n",ans); return; 33 } 34 35 int main(){ 36 work(); 37 return 0; 38 }

bzoj3676 [Apio2014]回文串