码迷,mamicode.com
首页 > Windows程序 > 详细

【bzoj3676】[Apio2014]回文串 回文自动机

时间:2017-08-16 09:58:09      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:裸题   define   pre   data   cst   统计   content   pac   efi   

题目描述

考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最大出现值。 

输入

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

输出

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

样例输入

【样例输入l】
abacaba
【样例输入2]
www

样例输出

【样例输出l】
7
【样例输出2]
4


题解

回文自动机裸题

关于PAM个人暂时理解不是很深入,挖坑待填。

本题只需要统计fail树的子树大小,再乘上回文串长度即可。

#include <cstdio>
#include <algorithm>
#define N 300010
using namespace std;
typedef long long ll;
int next[N][26] , fa[N] = {1 , 1} , len[N] = {0 , -1} , si[N] , tot = 1 , last;
char str[N];
void insert(int c , int now)
{
	int p = last;
	while(str[now - len[p] - 1] != str[now]) p = fa[p];
	if(!next[p][c])
	{
		int q = fa[p];
		while(str[now - len[q] - 1] != str[now]) q = fa[q];
		fa[++tot] = next[q][c] , next[p][c] = tot , len[tot] = len[p] + 2;
	}
	last = next[p][c] , si[last] ++ ;
}
int main()
{
	int i;
	ll ans = 0;
	scanf("%s" , str + 1);
	for(i = 1 ; str[i] ; i ++ ) insert(str[i] - ‘a‘ , i);
	for(i = tot ; i > 1 ; i -- ) ans = max(ans , (ll)si[i] * len[i]) , si[fa[i]] += si[i];
	printf("%lld\n" , ans);
	return 0;
}

 

 

【bzoj3676】[Apio2014]回文串 回文自动机

标签:裸题   define   pre   data   cst   统计   content   pac   efi   

原文地址:http://www.cnblogs.com/GXZlegend/p/7371424.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!