3676: [Apio2014]回文串

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 2343  Solved: 1031

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。

Source

【分析】

  听说回文自动机可以秒掉这题,以后再学吧。

  用串建SAM,然后求出right数组。

  manacher告诉我们,本质不同的回文串最多n个,只有在mx变的时候可能增加一个回文串。

  用manacher求出所有本质不同的回文串,然后在SAM上问。

  那就是问[L,R]这个区间的子串出现了多少次【感觉这个用后缀数组的话是nlogn^2的

  从SAM的pre边相当于AC自动机上的fail,形成一棵树,pre树上倍增即可。

  就是从POS[R]开始跳,当他代表的子串的长度大于r-l+1,即可计入答案,当然子串长度越小越好(更有可能出现最多次)

  【记得拓扑序

  【啊。。。卡空间。。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 301000
#define LL long long // int mymax(int x,int y) {return x>y?x:y;}
LL mymax(LL x,LL y) {return x>y?x:y;}
int mymin(int x,int y) {return x<y?x:y;} LL ans=; struct node
{
int pre,step,son[],rt;
}t[*Maxn];int last,tot;
int v[*Maxn],q[*Maxn],pos[*Maxn]; int ff[*Maxn][];
void get_f()
{
for(int i=;i<=tot;i++) ff[i][]=t[i].pre;
for(int i=;i<=tot;i++)
{
int nw=q[i];
for(int j=;j<=;j++)
ff[nw][j]=ff[ff[nw][j-]][j-];
}
} int now;
struct sam
{
void extend(int k)
{
int np=++tot,p=last;
t[np].step=t[last].step+;
t[np].rt=;pos[++now]=np;
while(p&&!t[p].son[k])
{
t[p].son[k]=np;
p=t[p].pre;
}
if(!p) t[np].pre=;
else
{
int q=t[p].son[k];
if(t[q].step==t[p].step+) t[np].pre=q;
else
{
int nq=++tot;
memcpy(t[nq].son,t[q].son,sizeof(t[nq].son));
t[nq].step=t[p].step+;
t[nq].pre=t[q].pre;
t[q].pre=t[np].pre=nq;
while(p&&t[p].son[k]==q)
{
t[p].son[k]=nq;
p=t[p].pre;
}
}
}
last=np;
}
void init()
{
memset(v,,sizeof(v));
for(int i=;i<=tot;i++) v[t[i].step]++;
for(int i=;i<=tot;i++) v[i]+=v[i-];
for(int i=tot;i>=;i--) q[v[t[i].step]--]=i; for(int i=tot;i>=;i--)
{
int nw=q[i];
t[t[nw].pre].rt+=t[nw].rt;
}
}
void ffind(int l,int r)
{
l=l/+;r=(r+)/;
int x=pos[r];
for(int i=;i>=;i--)
{
if(t[ff[x][i]].step>=r-l+) x=ff[x][i];
}
ans=mymax(ans,1LL*(r-l+)*t[x].rt);
}
}sam; char s[Maxn];
// int a[2*Maxn],p[2*Maxn]; void manacher(int l)
{
v[]=;
for(int i=;i<l;i++) v[*i+]=s[i]-'a'+,v[*i+]=;
v[*l+]=;
l=*l;
int mx=,id=;
for(int i=;i<=l;i++)
{
if(i<mx) q[i]=mymin(mx-i+,q[*id-i]);
else q[i]=;
while(v[i+q[i]]==v[i-q[i]]&&i-q[i]>=)
{
q[i]++;
sam.ffind(i-q[i]+,i+q[i]-);
}
if(i+q[i]->mx) mx=i+q[i]-,id=i;
}
} int main()
{
scanf("%s",s);
int l=strlen(s);
last=tot=;now=;
for(int i=;i<l;i++) sam.extend(s[i]-'a'+);
sam.init();
get_f();
manacher(l);
printf("%lld\n",ans);
return ;
}

2017-04-17 16:54:09

【BZOJ 3676】 3676: [Apio2014]回文串 (SAM+Manacher+倍增)的更多相关文章

  1. BZOJ3676:[APIO2014]回文串(SAM,Manacher)

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

  2. BZOJ3676 APIO2014回文串(manacher+后缀自动机)

    由于本质不同的回文子串数量是O(n)的,考虑在对于每个回文子串在第一次找到它时对其暴力统计.可以发现manacher时若右端点移动则找到了一个新回文串.注意这样会漏掉串长为1的情况,特判一下. 现在问 ...

  3. bzoj 3676 [Apio2014]回文串(Manacher+SAM)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3676 [题意] 给定一个字符串,定义一个串的权值为长度*出现次数,求最大权的回文子串. ...

  4. 【BZOJ 3676】[Apio2014]回文串

    [链接] 链接 [题意] 给你一个字符串s. 定义一个子串的出现值为它出现的次数*字符串的长度. 让你求里面的回文子串的最大出现值 |s|<=3e5 [题解] 马拉车算法里面. 只有在回文往外扩 ...

  5. bzoj3676 [Apio2014]回文串 卡常+SAM+树上倍增

    bzoj3676 [Apio2014]回文串 SAM+树上倍增 链接 bzoj luogu 思路 根据manacher可以知道,每次暴力扩展才有可能出现新的回文串. 所以推出本质不同的回文串个数是O( ...

  6. BZOJ 3676: [Apio2014]回文串

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2013  Solved: 863[Submit][Status ...

  7. bzoj 3676: [Apio2014]回文串 回文自动机

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 844  Solved: 331[Submit][Status] ...

  8. 3676: [Apio2014]回文串

    3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 1740 Solved: 744 [Submit][Status ...

  9. 3676: [Apio2014]回文串 求回文串长度与出现次数的最大值

    「BZOJ3676」[Apio2014] 回文串   Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所 ...

随机推荐

  1. JSDom

    什么是Dom? 1.简介 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口.Document Object Model的历史可 ...

  2. XML & JSON---iOS-Apple苹果官方文档翻译

      技术博客http://www.cnblogs.com/ChenYilong/   新浪微博http://weibo.com/luohanchenyilong   //转载请注明出处--本文永久链接 ...

  3. 【leetcode 简单】第十题 实现strStr()

    实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存在,则返 ...

  4. WordPress404页面自定义

    不知道大家是怎么设计404页面,个性的404可以为网站增色不少,wordpress设置404是在主题里面的404.php页面上,当然比如你用Apache.nginx等服务器,你可以自己建一个单页,内容 ...

  5. docker 升级后,配置 idea 连接 docker

    [root@A01-R02-I188-87 ~]# docker version Client: Version: 18.06.1-ce API version: 1.24 Go version: g ...

  6. Android中的通信Volley

    1. Volley简介 我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进行H ...

  7. perl6 struct2-045 EXP

    测试站点: http://www.yutian.com.cn/index.action http://www.hjxzyzz.com:8088/pfw/login.action 代码如下: use v ...

  8. python算法之近似熵、互近似熵算法

    理论基础 近似熵? 定义:近似熵是一个随机复杂度,反应序列相邻的m个点所连成折线段的模式的互相近似的概率与由m+1个点所连成的折线段的模式相互近似的概率之差. 作用:用来描述复杂系统的不规则性,越是不 ...

  9. vsftpd限速设置

    利用vsftp进行速率限制,需要了解几个配置参数 anon_max_rate 设置匿名用户每条连接最大上传或下载速率 local_max_rate 设置本地用户每条连接最大上传或下载速率 max_pe ...

  10. dpkg的用法 (转)

    dpkg是一个Debian的一个命令行工具,它可以用来安装.删除.构建和管理Debian的软件包. 下面是它的一些命令解释: 1)安装软件 命令行:dpkg -i <.deb file name ...