hihocoder 1419 重复旋律4
描述
小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为长度为 N 的数构成的数列。小Hi在练习过很多曲子以后发现很多作品中的旋律有重复的部分。
我们把一段旋律称为(k,l)-重复的,如果它满足由一个长度为l的字符串重复了k次组成。 如旋律abaabaabaaba是(4,3)重复的,因为它由aba重复4次组成。
小Hi想知道一部作品中k最大的(k,l)-重复旋律。
输入
一行一个仅包含小写字母的字符串。字符串长度不超过 100000。
输出
一行一个整数,表示答案k。
- Sample Input
- babbabaabaabaabab
- Sample Output
- 4
- 假如循环节长度为L
- 如果求出了后缀i和i+L的lcp
- 那么重复次数k=lcp(i,i+L)/L+1
- 那么O(n^2)的暴力有了,枚举L和i,计算k更新最大值
- 但是枚举i可以只枚举L的倍数,算出k
- 对于i和i+L,最多只会相差1
- 如果最优串的开始位置恰好在L的倍数上,那我们找到的最大的k就是正确答案
- 如果不在L的倍数上,那么最优的开始位置肯定在(i-L,i)上
- 如果lcp模L有余数,说明前面还需要补上L-lcp%L位,如果可行答案可以加1
- 于是可以判断开始位置为i-L+lcp%L与i+lcp%L的lcp
- 如果构成重复,那么算出来的
- k=lcp(i-L+lcp%L,i+lcp%L)/L+1=[lcp(i,i+L)/L+1]+1,比开始位置为i要好
- 于是复杂度:
- $O(\frac{n}{1}+\frac{n}{2}+\frac{n}{3}+...\frac{n}{n})$
- $=O(nlogn)$
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,c[],x[],y[],SA[],s[],rk[],h[];
int Min[][],Log[],ans;
char ch[];
void radix_sort()
{int i;
for (i=;i<=m;i++)
c[i]=;
for (i=;i<=n;i++)
c[x[y[i]]]++;
for (i=;i<=m;i++)
c[i]+=c[i-];
for (i=n;i>=;i--)
SA[c[x[y[i]]]--]=y[i];
}
void build_SA()
{int i,j,k,p;
for (i=;i<=n;i++)
x[i]=s[i],y[i]=i;
m=;
radix_sort();
for (k=;k<=n;k<<=)
{
p=;
for (i=n-k+;i<=n;i++)
y[++p]=i;
for (i=;i<=n;i++)
if (SA[i]>k) y[++p]=SA[i]-k;
radix_sort();
p=;swap(x,y);
x[SA[]]=;
for (i=;i<=n;i++)
x[SA[i]]=((y[SA[i]]==y[SA[i-]])&&(y[SA[i]+k]==y[SA[i-]+k]))?p:++p;
if (p>=n) break;
m=p;
}
for (i=;i<=n;i++)
rk[SA[i]]=i;
int L=;
for (i=;i<=n;i++)
{
if (L>) L--;
j=SA[rk[i]-];
while (i+L<=n&&j+L<=n&&(s[j+L]==s[i+L])) L++;
h[rk[i]]=L;
}
}
int rmq(int x,int y)
{
int L=Log[y-x+];
return min(Min[x][L],Min[y-(<<L)+][L]);
}
int lcp(int x,int y)
{
if (rk[x]>rk[y]) swap(x,y);
return rmq(rk[x]+,rk[y]);
}
int main()
{int i,j,L;
scanf("%s",ch);
n=strlen(ch);
for (i=;i<=n;i++)
{
s[i]=ch[i-]-'a'+;
}
build_SA();
memset(Min,/,sizeof(Min));
for (i=;i<=n;i++)
Min[i][]=h[i];
Log[]=;
for (i=;i<=n;i++)
Log[i]=Log[i/]+;
for (j=;(<<j)<=n;j++)
{
for (i=;i<=n-(<<j)+;i++)
Min[i][j]=min(Min[i][j-],Min[i+(<<j-)][j-]);
}
for (L=;L<=n;L++)
{
for (i=;i+L<=n;i+=L)
{
int p=lcp(i,i+L);
ans=max(ans,p/L+);
if (i-L+p%L>=)
{
ans=max(ans,lcp(i-L+p%L,i+p%L)/L+);
}
}
}
printf("%d\n",ans);
}
hihocoder 1419 重复旋律4的更多相关文章
- hihocoder 1407 重复旋律2
思路: 二分一哈答案 height分个块 //By SiriusRen #include <cstdio> #include <cstring> #include <al ...
- hihocoder #1419 : 后缀数组四·重复旋律4
#1419 : 后缀数组四·重复旋律4 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构 ...
- 【hihoCoder 1419】重复旋律4
Description 小 Hi 平时的一大兴趣爱好就是演奏钢琴. 我们知道一个音乐旋律被表示为长度为 N的数构成的数列. 小 Hi 在练习过很多曲子以后发现很多作品中的旋律有重复的部分. 我们把一段 ...
- 【简要题解】Hihocoder 重复旋律1-9简要题解
[简要题解]Hihocoder 重复旋律1-8简要题解 编号 名称标签 难度 1403 后缀数组一·重复旋律 Lv.4 1407 后缀数组二·重复旋律2 Lv.4 1415 后缀数组三·重复旋律3 L ...
- hihoCoder 后缀数组 重复旋律
#1403 : 后缀数组一·重复旋律 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成 ...
- HihoCoder 重复旋律
あの旋律を何度も繰り返しでも.あの日見た光景を再現できない 无论将那段旋律重复多少次,也无法重现那一日我们看到的景象 もし切ないならば.時をまきもどしてみるかい? 若是感到惆怅的话,要试着让时光倒流吗 ...
- hihoCoder 1403 后缀数组一·重复旋律(后缀数组+单调队列)
#1403 : 后缀数组一·重复旋律 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成 ...
- hihoCoder 后缀自动机三·重复旋律6
后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi ...
- hihoCoder #1445 : 后缀自动机二·重复旋律5
#1445 : 后缀自动机二·重复旋律5 时间限制:10000ms 单点时限:2000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...
随机推荐
- [福大软工] W班 总成绩排行榜
评分链接 作业1 作业2 作业3 作业4 总分排名
- alpha冲刺第五天
一.合照 二.项目燃尽图 三.项目进展 调整了一些界面的布局 细化了部分小功能的界面 注册界面和服务器响应了,但是在insert数据库方面出现了错误 四.明日规划 继续研究如何将注册的内容插入数据库 ...
- SQLSERVER2012的分页新功能
SQLSERVER2012的分页新功能 简介 SQL Server 2012中在Order By子句之后新增了OFFSET和FETCH子句来限制输出的行数从而达到了分页效果.相比较SQL Server ...
- 201621123031 《Java程序设计》第8周学习总结
作业08-集合 1.本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2.书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 源代码 ...
- tornado options
tornado.options.define() 用来定义options选项变量的方法,定义的变量可以在全局的tornado.options.options中获取使用,传入参数: name 选项变量名 ...
- idea 导eclipse项目
https://www.cnblogs.com/xiaoBlog2016/archive/2017/05/08/6825014.html
- ASP.NET MVC编程——单元测试
1自动化测试基本概念 自动化测试分为:单元测试,集成测试,验收测试. 单元测试 检验被测单元的功能,被测单元一般为低级别的组件,如一个类或类方法. 单元测试要满足四个条件:自治的,可重复的,独立的,快 ...
- Unix下zfs文件系统重组RAID-5后可以这样恢复
存储做的RAID-5, SCSI硬盘,操作系统是FreeBSD,文件系统是zfs.本案例共有12块硬盘,11块硬盘里有数据,1块硬盘是热备盘.其中第6块数据硬盘出现故障,重组时需要将其剔除. 物理盘: ...
- js判断flash文件是否加载完毕
轮询判断加载进度 img的加载完成有onload方法,一直不知道该怎么判断swf文件是否加载完毕了? 在应用中使用了轮询判断加载进度值PercentLoaded是否达到100,经测试,可以达到效果. ...
- sublime的使用技巧
ctr+shift+d是复制当前行当下一行2.使用Sublime text 3 编写代码是一种享受,使用Sublime text 3 格式化HTML代码,需要安装插件,具体安装步骤如下:1.打开菜单- ...