3676: [Apio2014]回文串

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 3097  Solved: 1408
[Submit][Status][Discuss]

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。

代码总用时:3h

很简单的一道题,只要意识到Manacher算法的本质(本质不同的回文串的个数是O(n)的),配合后缀自动机或者后缀数组就可以轻松解决。

但这道题调了好久,浪费了很多时间,一是因为后缀自动机模板不熟练,而是Manacher算法流程没有一个清楚的认识。

写代码的时候精力要高度集中,不能因为低级错误耽误时间。

下面是SAM版本的代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #define rep(i,l,r) for (int i=l; i<=r; i++)
  5. typedef long long ll;
  6. using namespace std;
  7.  
  8. const int N=;
  9. int cnt=,lst=,n,tot[N],mx[N],p[N],pos[N],son[N][],fa[N],f[N][],q[N],R[N];
  10. ll ans; char s[N],S[N];
  11.  
  12. void ext(int c,int x){
  13. int p=lst,np=lst=++cnt; mx[np]=mx[p]+; R[np]=; pos[x]=np;
  14. while (!son[p][c] && p) son[p][c]=np,p=fa[p];
  15. if (!p) fa[np]=;
  16. else{
  17. int q=son[p][c];
  18. if (mx[q]==mx[p]+) fa[np]=q;
  19. else{
  20. int nq=++cnt; mx[nq]=mx[p]+;
  21. memcpy(son[nq],son[q],sizeof(son[q]));
  22. fa[nq]=fa[q]; fa[q]=fa[np]=nq;
  23. while (son[p][c]==q && p) son[p][c]=nq,p=fa[p];
  24. }
  25. }
  26. }
  27.  
  28. void pre(){
  29. rep(i,,cnt) tot[mx[i]]++;
  30. rep(i,,n) tot[i]+=tot[i-];
  31. for (int i=cnt; i; i--) q[tot[mx[i]]--]=i;
  32. for (int i=cnt; i; i--) R[fa[q[i]]]+=R[q[i]];
  33. rep(i,,cnt){
  34. f[i][]=fa[i];
  35. rep(j,,) f[i][j]=f[f[i][j-]][j-];
  36. }
  37. }
  38.  
  39. void get(int l,int r){
  40. l=(l>>)+(l&); r>>=; int x=pos[r];
  41. for (int i=; ~i; i--)
  42. if (mx[f[x][i]]>=r-l+) x=f[x][i];
  43. ans=max(ans,1ll*R[x]*(r-l+));
  44. }
  45.  
  46. void manacher(){
  47. int mxlen=,id;
  48. rep(i,,n){
  49. if (mxlen>i) p[i]=min(mxlen-i,p[*id-i]);
  50. else{ p[i]=; if (S[i]!='#') get(i,i); }
  51. while (S[i+p[i]]==S[i-p[i]]) get(i-p[i],i+p[i]),p[i]++;
  52. if (p[i]+i>mxlen) mxlen=p[i]+i,id=i;
  53. }
  54. }
  55.  
  56. int main(){
  57. freopen("palindromes.in","r",stdin);
  58. freopen("palindromes.out","w",stdout);
  59. scanf("%s",s+); n=strlen(s+);
  60. rep(i,,n) ext(s[i]-'a',i);
  61. pre(); S[]='$'; S[]='#';
  62. rep(i,,n) S[(i<<)+]='#',S[i<<]=s[i];
  63. n=(n<<)+; manacher(); printf("%lld\n",ans);
  64. return ;
  65. }

[BZOJ3676][APIO2014]回文串(Manacher+SAM)的更多相关文章

  1. BZOJ3676: [Apio2014]回文串(SAM+Manacher/PAM)

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

  2. [bzoj3676][Apio2014]回文串——Manacher+后缀自动机+倍增

    Brief Description 一个回文串的value定义为这个回文串的长度乘以出现次数.给定一个字符串,求\(value_{max}\). Algorithm Design 我们使用Manach ...

  3. BZOJ3676 APIO2014 回文串 Manacher、SA

    传送门 首先一个结论:串\(S\)中本质不同的回文串个数最多有\(|S|\)个 证明考虑以点\(i\)结尾的所有回文串,假设为\(S[l_1,i],S[l_2,i],...,S[l_k,i]\),其中 ...

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

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

  5. [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串

    回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...

  6. 【BZOJ 3676】 3676: [Apio2014]回文串 (SAM+Manacher+倍增)

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2343  Solved: 1031 Description 考 ...

  7. [Bzoj3676][Apio2014]回文串(后缀自动机)(parent树)(倍增)

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 3396  Solved: 1568[Submit][Statu ...

  8. 【BZOJ3676】 [Apio2014]回文串(SAM,manacher)

    传送门 BZOJ 洛谷 Solution 考虑我们每找到一个回文串就更新一次答案,跑个SAM,这样子复杂度是爆炸的. 接下来的就是优化: 我们可以倍增跳直到跳不了,最后的siz就是出现次数. 没了?没 ...

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

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

随机推荐

  1. 【BZOJ】2466: [中山市选2009]树 高斯消元解异或方程组

    [题意]给定一棵树的灯,按一次x改变与x距离<=1的点的状态,求全0到全1的最少次数.n<=100. [算法]高斯消元解异或方程组 [题解]设f[i]=0/1表示是否按第i个点的按钮,根据 ...

  2. HDU 1214 圆桌会议 (找规律)

    题目链接 Problem Description HDU ACM集训队的队员在暑假集训时经常要讨论自己在做题中遇到的问题.每当面临自己解决不了的问题时,他们就会围坐在一张圆形的桌子旁进行交流,经过大家 ...

  3. python初步学习-python文件操作

    文件 文件,在python中,他是一种类型的对象,类似前面已经学过的其他数据类型,包括文本的.图片的.音频的.视频的等等,还有不少没见过的扩展名的.事实上,在linux操作系统中,所有的东西都被保存到 ...

  4. 使用chardet判断编码方式

    1. chardet是什么 chardet是python中比较常用的一个编码方式检测库,需要注意的是它只检测并返回检测结果,并不负责对原数据做什么处理. 可以使用PIP命令安装: pip instal ...

  5. 23、Xpath

    1.什么是Xpath?1.XPath即为XMLPath的简称,它是一种用来确定XML文档中某部分位置的语言.2.HTML可以看做是XML的一种实现,所以selenium用户可以使用这种强大的语言在we ...

  6. 2. 数据库文件配置与简单操作 Model / M()

    官方文档说明位置: Thinkphp/Conf/convention.php 内容说明如下: 'DB_TYPE' => '', // 数据库类型 'DB_HOST' => '', // 服 ...

  7. Spring如何解析Dubbo标签

    1. 要了解Dubbo是如何解析标签的,首先要清楚一点就是Spring如何处理自定义标签的,因为Dubbo的标签可以算是Spring自定义标签的一种情况: 2. Spring通过两个接口来解析自定义的 ...

  8. appium---【Mac】appium-doctor提示WARN:“fbsimctl cannot be found”解决方案

    报错提示截图如下: 解决方案: brew tap facebook/fb brew install fbsimctl --HEAD 执行完命令重新运营appium-doctor即可看到成功已安装此包:

  9. JS模块化规范AMD之RequireJS

    1.基本操作 加载 JavaScript 文件(入口文件) RequireJS以一个相对于baseUrl的地址来加载所有的代码 <script data-main="scripts/m ...

  10. 大理石在哪儿(UVa10474)

    题目具体描述见:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=835&a ...