回文串(bzoj 3676)
Description
考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出
现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最
大出现值。
Input
输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。
Output
输出一个整数,为逝查回文子串的最大出现值。
Sample Input
abacaba
【样例输入2]
www
Sample Output
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。
/*
调了一个晚上,终于调出来了,二分的时候出了一些差错。
因为一个长度为n的字符串,本质不同的回文串只有n个,所以这个题很明显需要处理出所有的回文串,然后再查询字符串中它出现的次数。
提前处理出height数组,然后查询某个字串的时候,找到它的排名,向上向下二分查询次数。
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 300100
#define lon long long
using namespace std;
int s[N],t1[N],t2[N],c[N],sa[N],rank[N],height[N],n,m=;
int p[N*],st[N][],lg2[N];
char ch[N],s1[N*];lon ans;
bool cmp(int *y,int a,int b,int k){
int a1=y[a],b1=y[b];
int a2=a+k<n?y[a+k]:-;
int b2=b+k<n?y[b+k]:-;
return a1==b1&&a2==b2;
}
void DA(){
int *x=t1,*y=t2;
for(int i=;i<m;i++) c[i]=;
for(int i=;i<n;i++) c[x[i]=s[i]]++;
for(int i=;i<m;i++) c[i]+=c[i-];
for(int i=n-;~i;i--) sa[--c[x[i]]]=i;
for(int k=,p=;k<=n;k*=,m=p,p=){
for(int i=n-k;i<n;i++) y[p++]=i;
for(int i=;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(int i=;i<m;i++) c[i]=;
for(int i=;i<n;i++) c[x[y[i]]]++;
for(int i=;i<m;i++) c[i]+=c[i-];
for(int i=n-;~i;i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);p=;x[sa[]]=;
for(int i=;i<n;i++)
if(cmp(y,sa[i-],sa[i],k)) x[sa[i]]=p-;
else x[sa[i]]=p++;
if(p>=n) break;
}
}
void get_ht(){
for(int i=;i<n;i++) rank[sa[i]]=i;
for(int i=,j,k=;i<n;height[rank[i++]]=k){
if(!rank[i]) continue;
j=sa[rank[i]-];k=k?k-:k;
while(j+k<n&&i+k<n&&s[i+k]==s[j+k]) k++;
}
memset(st,/,sizeof(st));
for(int i=;i<n;i++) st[i][]=height[i];
for(int i=;i<=n;i++) lg2[i]=lg2[i>>]+;
for(int j=;<<j<=n;j++)
for(int i=;i+(<<j)-<n;i++)
st[i][j]=min(st[i][j-],st[i+(<<j-)][j-]);
}
int query(int l,int r){
if(l>r) return ;
int k=lg2[r-l+];
return min(st[l][k],st[r-(<<k)+][k]);
}
lon solve(int l,int r){
l=(l&)?l/:l/-;
r=(r&)?r/-:r/-;
if(l==&&r==){
int aa=;
}
int pos=rank[l],L=-,R=pos,tmp1=pos,tmp2=pos;
while(L<R-){
int mid=L+R>>;
if(query(mid+,pos)>=r-l+) R=mid,tmp1=mid;
else L=mid;
}
L=pos;R=n;
while(L<R-){
int mid=L+R>>;
if(query(pos+,mid)>=r-l+) L=mid,tmp2=mid;
else R=mid;
}
return (lon)(tmp2-tmp1+)*(r-l+);
}
void manacher(){
int len=n*+;
s1[]='$';s1[len]='#';
for(int i=;i<n;i++){
s1[i*+]='#';
s1[i*+]=ch[i];
}
p[]=;int pos=,maxr=;
for(int i=;i<=len;i++){
if(i<maxr) p[i]=min(maxr-i,p[pos*-i]);
else p[i]=;
while(s1[i+p[i]]==s1[i-p[i]]){
if(i+p[i]>maxr) ans=max(ans,solve(i-p[i],i+p[i]));
p[i]++;
}
if(i+p[i]>maxr) pos=i,maxr=i+p[i];
}
}
int main(){
scanf("%s",ch);n=strlen(ch);
for(int i=;i<n;i++) s[i]=ch[i]-'a';
DA();get_ht();
manacher();
cout<<ans;
return ;
}
回文串(bzoj 3676)的更多相关文章
- 回文树(回文自动机) - BZOJ 3676 回文串
BZOJ 3676 回文串 Problem's Link: http://www.lydsy.com/JudgeOnline/problem.php?id=3676 Mean: 略 analyse: ...
- 2565: 最长双回文串 - BZOJ
Description 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同). 输入长度为n的串S,求S的最长双回文子串T ...
- Manacher || P4555 [国家集训队]最长双回文串 || BZOJ 2565: 最长双回文串
题面:P4555 [国家集训队]最长双回文串 题解:就.就考察马拉车的理解 在原始马拉车的基础上多维护个P[i].Q[i]数组,分别表示以i结尾最长回文子串的长度和以i开头的最长回文子串的长度 然后就 ...
- 【bzoj3676】[Apio2014]回文串 —— 回文自动机的学习
写题遇上一棘手的题,[Apio2014]回文串,一眼看过后缀数组+Manacher.然后就码码码...过是过了,然后看一下[Status],怎么慢这么多,不服..然后就搜了一下,发现一种新东西——回文 ...
- 【BZOJ】【3676】【APIO2014】回文串
回文自动机/Manacher+SA 这道题可以用Manacher找出本质不同的回文串(令max增大的所有回文串),然后再用SA跑出来有多少相同. 还有一种做法就是回文自动机(Orz Hzwer)的裸题 ...
- BZOJ 3676: [Apio2014]回文串
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2013 Solved: 863[Submit][Status ...
- 【BZOJ】3676: [Apio2014]回文串
http://www.lydsy.com/JudgeOnline/problem.php?id=3676 题意:给一个串求回文串×出现次数的最大值.(|S|<=300000) #include ...
- bzoj 3676: [Apio2014]回文串 回文自动机
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 844 Solved: 331[Submit][Status] ...
- BZOJ 3676 回文串
Description 考虑一个只包含小写拉丁字母的字符串\(s\).我们定义\(s\)的一个子串\(t\)的"出现值"为\(t\)在\(s\)中的出现次数乘以\(t\)的长度.请 ...
随机推荐
- c++ 程序设计question 001:我们的开发工具是什么?
我们使用的开发工具是dev cpp (c plus plus),这是一个集成开发环境,我们称之为IDE(integrated development environment)
- 使用 RuPengGame游戏引擎包 建立游戏窗体 如鹏游戏引擎包下载地址 Thread Runnable 卖票实例
package com.swift; import com.rupeng.game.GameCore;//导入游戏引擎包 //实现Runnable接口 public class Game_RuPeng ...
- require.js模块化开发
模块化开发的原因: 1.引入的js过多然后在加载的过程中容易出现假死的状态,导致页面会发生白屏 2.变量名的问题 在多人协作开发的时候容易出现变量名的冲突 面向对象 3.引入优先级的问题 模块化开发分 ...
- 十一、Shell 文件包含
Shell 文件包含 和其他语言一样,Shell 也可以包含外部脚本.这样可以很方便的封装一些公用的代码作为一个独立的文件. Shell 文件包含的语法格式如下: . filename # 注意点号( ...
- Mbps、Kbps、bps、kb、mb区别和换算
Mbps 即 Milionbit pro second(百万位每秒) Kbps 即 Kilobit pro second(千位每秒) bps 即 bit pro second(位每秒) 速度单位,bi ...
- 获取页面URL参数值
JavaScript function GetParams(urlAddress) { var i, strLength, str, keyName, keyValue, params = {}, u ...
- js数据结构与算法--递归
递归,函数自己调用自己 return 返回值, 后面的代码不执行 function fn(num){ console.log(num) if(num == 0){ return; } fn(num-1 ...
- PHP 优化
来源:歪麦博客 https://www.awaimai.com/1050.html 1 字符串 1.1 少用正则表达式 能用PHP内部字符串操作函数的情况下,尽量用他们,不要用正则表达式, 因为其效率 ...
- mysql中的FROM_UNIXTIME()函数和UNIX_TIMESTAMP()函数
unix_timestamp 是时间戳,可以用数据库里的存储时间数据的字段 from_unixtime 是将时间戳格式化为你想要时间
- JZOJ 5462. 【NOIP2017提高A组冲刺11.8】好文章
5462. [NOIP2017提高A组冲刺11.8]好文章 (File IO): input:article.in output:article.out Time Limits: 1000 ms M ...