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。

  这道题要求出每一个回文串,以及出现的次数。

  先用马拉车算法求出每个位置最长的回文子串,可以证明:从每个位置上取出最长的回文串去枚举一定能枚举出最优解。

  接着对于,每个位置的最长回文子串用SA与ST快速求出其出现的次数,然而这并非正解,回文自动机才是(话说APIO2014的时候还没有这玩意儿),那时这个算法应该是最优的了。

 #include <iostream>
 #include <cstring>
 #include <cstdio>
 using namespace std;
 ;
 ];
 ];
 ],maxL[maxn];
 int rank[maxn],Wa[maxn],Wb[maxn],Wv[maxn],Ws[maxn],sa[maxn],r[maxn];
 int lcp[maxn],len;
 ];
 bool cmp(int *p,int a,int b,int l){
     return p[a]==p[b]&&p[a+l]==p[b+l];
 }

 void DA(int n,int m){
     int i,j,p,*x=Wa,*y=Wb,*t;
     ;i<m;i++)Ws[i]=;
     ;i<n;i++)++Ws[x[i]=r[i]];
     ;i<m;i++)Ws[i]+=Ws[i-];
     ;i>=;i--)sa[--Ws[x[i]]]=i;

     ,p=;p<n;j<<=,m=p){
         ,i=n-j;i<n;i++)y[p++]=i;
         ;i<n;i++)
             if(sa[i]>=j)
                 y[p++]=sa[i]-j;

         ;i<m;i++)Ws[i]=;
         ;i<n;i++)++Ws[Wv[i]=x[y[i]]];
         ;i<m;i++)Ws[i]+=Ws[i-];
         ;i>=;i--)sa[--Ws[Wv[i]]]=y[i];
         ]]=,i=,p=;i<n;i++)
             x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
     }
 }

 void Lcp(int n){
     ;
     ;i<=n;i++)rank[sa[i]]=i;
     ;i<n;lcp[rank[i++]]=k)
         ];r[j+k]==r[i+k];++k);
 }
 int Qmin(int l,int r){
     ]],Min[r-(<<mm[r-l+])+][mm[r-l+]]);
 }

 int Query(int p,int l){
     ,lo,hi;
     hi=rank[p];lo=;
     while(lo<=hi){
         ;
         ;
         ;
     }
     ret+=rank[p]-lo+;    

     hi=len;lo=rank[p]+;
     while(lo<=hi){
         ;
         ,mid)>=l)lo=mid+;
         ;
     }
     return ret+hi-rank[p];
 }

 int main(){
     scanf("%s",s);
     len=strlen(s);
     ;
     S[l++]='#';S[l++]='&';
     ;i<len;i++){
         pos[l]=i;
         S[l++]=s[i];
         pos[l]=i+;
         S[l++]='&';
     }
     S[l]=;
     ,id;
     ;i<l;i++){
         maxl[i]=mx>i?min(maxl[id*-i],mx-i):;
         while(S[i+maxl[i]]==S[i-maxl[i]])maxl[i]++;
         if(i+maxl[i]>mx){
             mx=i+maxl[i];
             id=i;
         }
     }

     ;i<=l;i++)
         maxL[pos[i-maxl[i]+]]=max(maxL[pos[i-maxl[i]+]],maxl[i]-);
     //maxL[i]原s字符串中i位置最长回文子串
     ;i<len;i++)r[i]=s[i];
     DA(len+,);
     Lcp(len);

     mm[]=-;
     ;i<=len;i++){
         mm[i]=(i&(i-))?mm[i-]:mm[i-]+;
         Min[i][]=lcp[i];
     }

     ;k<=mm[len];k++)
     ;i+(<<k)-<=len;i++)
     Min[i][k]=min(Min[i][k-],Min[i+(<<(k-))][k-]);

     ;
     ;i<len;i++){
         ans=max(ans,1ll*maxL[i]*Query(i,maxL[i]));
     }
     printf("%lld\n",ans);
     ;
 }

  然后还有一种方法,前面提过,回文自动机:

 #include <iostream>
 #include <cstdio>
 using namespace std;
 ;
 ],fail[maxn],len[maxn],num[maxn];
 ;
 char s[maxn];
 int find(int i,int x){
     ]!=s[i])x=fail[x];
     return x;
 }
 int main(){
     scanf("%s",s);
     fail[]=;len[]=-;cnt=;
     ;s[i];i++){
         int j=find(i,last);
         if(ch[j][s[i]-'a'])
             last=ch[j][s[i]-'a'];
         else{
             len[last=++cnt]=len[j]+;
             fail[last]=ch[find(i,fail[j])][s[i]-'a'];
             ch[j][s[i]-'a']=last;
         }
         num[last]++;
     }
     ;i--)
         ans=max(ans,1ll*num[i]*len[i]),num[fail[i]]+=num[i];
     printf("%lld\n",ans);
     ;
 }

  超级短,超级简单,但还是有些地方要注意:

  14行的初始化不能乱改,改了挺麻烦的;21,22行是有顺序的,写反了会死循环。

字符串(马拉车算法,后缀数组,稀疏表):BZOJ 3676 [Apio2014]回文串的更多相关文章

  1. BZOJ 3676: [Apio2014]回文串

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

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

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

  3. BZOJ 3676 [Apio2014]回文串 (后缀自动机+manacher/回文自动机)

    题目大意: 给你一个字符串,求其中回文子串的长度*出现次数的最大值 明明是PAM裸题我干嘛要用SAM做 回文子串有一个神奇的性质,一个字符串本质不同的回文子串个数是$O(n)$级别的 用$manach ...

  4. ●BZOJ 3676 [Apio2014]回文串

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3676 题解: 后缀数组,Manacher,二分 首先有一个结论:一个串的本质不同的回文串的个 ...

  5. BZOJ 3676 [Apio2014]回文串(回文树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3676 [题目大意] 考虑一个只包含小写拉丁字母的字符串s. 我们定义s的一个子串t的& ...

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

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

  7. BZOJ.3676.[APIO2014]回文串(回文树)

    BZOJ 洛谷 很久之前写(抄)过一个Hash+Manacher的做法,当时十分懵逼=-= 然而是道回文树模板题. 回文树教程可以看这里(真的挺妙的). 顺便再放上MilkyWay的笔记~ //351 ...

  8. BZOJ 3676: [Apio2014]回文串 后缀自动机 Manacher 倍增

    http://www.lydsy.com/JudgeOnline/problem.php?id=3676 过程很艰难了,第一次提交Manacher忘了更新p数组,超时,第二次是倍增的第0维直接在自动机 ...

  9. bzoj 3676: [Apio2014]回文串【后缀自动机+manacher】

    用manacher找出本质不同的回文子串放在SAM上跑 #include<iostream> #include<cstdio> #include<cstring> ...

随机推荐

  1. 150925-周五不干活-HTML(CSS),Javascript

    不干活就干自己.. 今天所有代码总结为一个如下 <!DOCTYPE HTML><html><head><meta http-equiv="Conte ...

  2. 自动attach到iis

    可以不用手动attachToProcess. 先找到自己的网站Solution.右键property 2) 3)保存后  可以看到process 当前进程就是w3p3的iis的进程名字

  3. 导航程序调试1---MFC应用以及数据显示程序

    问题 error C2664: "BuildCommDCBW": 不能将参数 1 从"char *"转换为"LPCWSTR"经常出现这样的错 ...

  4. ASP.NET服务器控件使用之MultiView和View

    MultiView 控件是一组 View 控件的容器.使用它可定义一组 View 控件,其中每个 View 控件都包含子控件. 用 ActiveViewIndex 属性或SetActiveView 方 ...

  5. Motan:目录结构

    motan是由maven管理的,在最外层的pom.xml中可以看出这个项目有多个模块组成. <modules> <module>motan-core</module> ...

  6. hdu 4685 简单匹配+Tarjan算法

    思路:首先看到这题以为能用poj1904的模版直接A掉,WA了几次,然后又TLE了几次.还是想到了正解. 一开始我想的大致方向已经是对的了.先是由王子向每个喜欢的公主建边,再求一次最大匹配,找出匹配后 ...

  7. 性能测试资源监控工具nmon使用方法

    1.简述  nmon是一种在AIX与各种Linux操作系统上广泛使用的监控与分析工具,相对于其它一些系统资源监控工具来说,nmon所记录的信息是比较全面的,它能在系统运行过程中实时地捕捉系统资源的使用 ...

  8. STM32 下的库函数和寄存器操作比较

    以 led闪烁中的flashLed函数例子: 库函数操作简单,但是效率不如寄存器操作的高: 寄存器操作很复杂,因为要熟悉上百个寄存器,但是程序效率很高 /**下面是通过直接操作库函数的方式实现IO控制 ...

  9. SpriteBuilder中应用智能精灵集之后提示找不到文件的解决

    SpriteBuilder中有一个将方便的功能,可以用文件夹中的若干图片生成1张图片;这称之为智能精灵集合(smart sprite sheet).好处是可以一次性的加载图片到显存中去,提升了性能. ...

  10. js的柯里化currying

    转载:http://www.zhangxinxu.com/wordpress/2013/02/js-currying/ 我自己的理解柯里化就是这样的,(1)必须返回匿名函数,(2)参数复用. 1. 参 ...