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平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...
随机推荐
- ThreadLocal 原理和使用场景分析
ThreadLocal 不知道大家有没有用过,但至少听说过,今天主要记录一下 ThreadLocal 的原理和使用场景. 使用场景 直接定位到 ThreadLocal 的源码,可以看到源码注释中有很清 ...
- EM算法的直观描述
解决含有隐变量的问题有三种方法,其中第三种方法就是通常所说的em算法.下面以统计学习方法中给出的三硬币问题为例来分别描述这三种方法.(a,b,c三硬币抛出来为正的概率分别为pai,p,q,每轮抛硬币先 ...
- C语言程序设计(基础)- 第7周作业(新)
要求一(25经验值) 完成PTA中题目集名为<usth-C语言基础-第七周作业>和<usth-C语言基础-12周PTA作业>中的所有题目. 注意1:<usth-C语言基础 ...
- requestAnimationFrame Web中写动画的另一种选择
HTML5和CSS3盛行的今天 动画变得很简单实现 我们可以用transition . animation + keyframe .也可以用canvas等 我在上一篇 点击回到顶部的文章中发现的这个 ...
- Jetty入门(1-3)Eclipse集成gradle-Gretty插件或maven-jetty插件运行应用
英文来源: http://akhikhl.github.io/gretty-doc/Getting-started.html 一.gradle插件 1.使用gretty来运行jetty: gradl ...
- Spark-1.X编译构建及配置安装
前提条件(环境要求) jdk版本:1.7+ scala版本:1.10.4+ maven版本:3.3.3+ 本博客中使用的软件版本 spark版本:spark-1.6.1.tar.gz(源码) jdk版 ...
- PyMySQL模块的使用
PyMySQL介绍 PyMySQL是在Python3.x版本中用于连接MySQL服务器的一个库,Python2系列中则使用mysqldb.Django中也可以使用PyMySQL连接MySQL数据库. ...
- 【第二十篇】C#微信H5支付 非微信内浏览器H5支付 浏览器微信支付
微信开发者文档 微信H5支付官方文档 请阅读清楚 最起码把所有参数看一遍 这个地方也可以看看 微信案例 http://wxpay.wxutil.com/mch/pay/h5.v2.php,请在微 ...
- python--socket粘包
socket粘包 1 什么是粘包 须知:只有TCP有粘包现象,UDP永远不会粘包,首先需要掌握一个socket收发消息的原理, 所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少 ...
- 南阳OJ-2-括号配对问题---栈的应用
题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=2 题目大意: 有一行括号序列,请你检查这行括号是否配对. 思路: 直接用栈来模拟 ...