POJ1743:Musical Theme——题解
http://poj.org/problem?id=1743
给一段数,求最大相似子串长度,如果没有输出0。
相似子串定义:
1.两个不重叠的子串,其中一个是另一个加/减一个数得来的。
2.长度>=5
二分答案,然后想如何表示相似。
实际上我们对原数进行差分然后找相同不重叠子串即可,答案为长度+1。
但是我们考虑对于1 2 3这组数据答案为1(虽然你应该输出0),而用上面的方法会得到2,显然是不对的。
实际上上面差分得1 1 -3,1和1虽然为相同不重叠子串,但在原数组上他们是重叠的,所以我们规定两个子串之间必须差一个数。
具体的方法就是处理高度函数,找每个后缀的最长公共前缀即可。
细节:
处理高度函数和二分答案的时候要把末尾的数去掉。
数字不可为负,为此可以同时加上一个数。
- #include<algorithm>
- #include<iostream>
- #include<cstring>
- #include<cctype>
- #include<cstdio>
- #include<vector>
- #include<queue>
- #include<cmath>
- using namespace std;
- const int N=2e4+;
- int n,rank[N],sa[N],height[N],w[N],s[N];
- inline bool pan(int *x,int i,int j,int k){
- int ti=i+k<n?x[i+k]:-;
- int tj=j+k<n?x[j+k]:-;
- return x[i]==x[j]&&ti==tj;
- }
- inline void SA_init(){
- int *x=rank,*y=height,r=;
- for(int i=;i<r;i++)w[i]=;
- for(int i=;i<n;i++)w[s[i]]++;
- for(int i=;i<r;i++)w[i]+=w[i-];
- for(int i=n-;i>=;i--)sa[--w[s[i]]]=i;
- r=;x[sa[]]=;
- for(int i=;i<n;i++)
- x[sa[i]]=s[sa[i]]==s[sa[i-]]?r-:r++;
- for(int k=;r<n;k<<=){
- int yn=;
- for(int i=n-k;i<n;i++)y[yn++]=i;
- for(int i=;i<n;i++)
- if(sa[i]>=k)y[yn++]=sa[i]-k;
- for(int i=;i<r;i++)w[i]=;
- for(int i=;i<n;i++)++w[x[y[i]]];
- for(int i=;i<r;i++)w[i]+=w[i-];
- for(int i=n-;i>=;i--)sa[--w[x[y[i]]]]=y[i];
- swap(x,y);r=;x[sa[]]=;
- for(int i=;i<n;i++)
- x[sa[i]]=pan(y,sa[i],sa[i-],k)?r-:r++;
- }
- for(int i=;i<n;i++)rank[i]=x[i];
- }
- inline void height_init(){
- int i,j,k=;
- for(i=;i<=n;i++)rank[sa[i]]=i;
- for(i=;i<n;i++){
- if(k)k--;
- else k=;
- j=sa[rank[i]-];
- while(s[i+k]==s[j+k])k++;
- height[rank[i]]=k;
- }
- }
- bool check(int k){
- int maxn,minn;
- maxn=minn=sa[];
- for(int i=;i<=n;i++){
- if(height[i]>=k&&i<n){
- minn=min(minn,sa[i]);
- maxn=max(maxn,sa[i]);
- continue;
- }
- if(maxn-minn>=k)return ;
- maxn=minn=sa[i];
- }
- return ;
- }
- int erfen(int l,int r){
- while(l<r){
- int mid=(l+r+)>>;
- if(check(mid))l=mid;
- else r=mid-;
- }
- if(l<)return ;
- return l+;
- }
- int main(){
- while(scanf("%d",&n)!=EOF&&n){
- for(int i=;i<n;i++)scanf("%d",&s[i]);
- for(int i=;i<n-;i++)s[i]=s[i+]-s[i]+;
- s[n-]=;
- SA_init();
- n--;
- height_init();
- printf("%d\n",erfen(,n));
- }
- return ;
- }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
POJ1743:Musical Theme——题解的更多相关文章
- POJ1743 Musical Theme —— 后缀数组 重复出现且不重叠的最长子串
题目链接:https://vjudge.net/problem/POJ-1743 Musical Theme Time Limit: 1000MS Memory Limit: 30000K Tot ...
- POJ1743 Musical Theme [后缀数组]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- POJ1743 Musical Theme [后缀数组+分组/并查集]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- poj1743 Musical Theme【后缀数组】【二分】
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 35044 Accepted: 11628 D ...
- POJ-1743 Musical Theme,后缀数组+二分!
Musical Theme 人生第一道后缀数组的题,采用大众化思想姿势极其猥琐. 题意:给你n个 ...
- POJ1743 Musical Theme
Description A musical melody is represented as a sequence of N (1<=N<=20000)notes that are int ...
- POJ1743 Musical Theme (后缀数组 & 后缀自动机)最大不重叠相似子串
A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...
- POJ1743 Musical Theme(后缀数组 二分)
Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 33462 Accepted: 11124 Description A m ...
- POJ-1743 Musical Theme(最长不可重叠子串,后缀数组+二分)
A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...
随机推荐
- 数据库路由中间件MyCat - 背景篇(2)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. MyCat的前世今生 如前文所说,Amoeba.Cobar.MyCat等属于同宗一脉.若Amoeba能继续下 ...
- 基于Docker的UI自动化初探
本文来自网易云社区 前言 一直以来,项目迭代的时间都是比较紧张的,开发加班加点coding,测试加班加点提bug.都说"时间像海绵里的水,挤挤总会有的"(当然这里的"挤挤 ...
- 一个只有十行的精简MVVM框架(上篇)
本文来自网易云社区. 前言 MVVM模式相信做前端的人都不陌生,去网上搜MVVM,会出现一大堆关于MVVM模式的博文,但是这些博文大多都只是用图片和文字来进行抽象的概念讲解,对于刚接触MVVM模式的新 ...
- linux部署MantisBT(二)部署php
二.部署php 1.下载php安装包 http://php.net/downloads.php 2.安装php yum install libxml2 yum install libxml2-deve ...
- MATLAB实现连续周期信号的频谱分析(正余弦波信号举例)
关于MATLAB实现连续信号的频谱分析,以正余弦波信号频谱分析为例分析如下: 1.含有频率f ,2f和3f的正弦波叠加信号,即: 其中,f =500Hz.试采用Matlab仿真软件对该信号进行频谱分析 ...
- Unity编辑器 - 输入控件聚焦问题
Unity编辑器整理 - 输入控件聚焦问题 EditorGUI的输入控件在聚焦后,如果在其他地方改变值,聚焦的框不会更新,而且无法取消聚焦,如下图: 在代码中取消控件的聚焦 取消聚焦的"时机 ...
- ubuntu 执行Python脚本出现: /usr/bin/env: ‘python\r’: No such file or directory
原因: #!/usr/bin/env python 在ubuntu会变成 #!/usr/bin/env python\r 而\r 会被shell 当成参数 所以出现: /usr/bin/env: ‘ ...
- 凸包算法(Graham扫描法)详解
先说下基础知识,不然不好理解后面的东西 两向量的X乘p1(x1,y1),p2(x2,y2) p1Xp2如果小于零则说明 p1在p2的逆时针方向 如果大于零则说明 p1在p2的顺时针方向 struct ...
- Spark- 根据IP获取城市(java)
开源 IP 地址定位库 ip2region 1.4 ip2region 是准确率 99.9% 的 IP 地址定位库,0.0x毫秒级查询,数据库文件大小只有 2.7M,提供了 Java.PHP.C.Py ...
- Spark mlib的本地向量
Spark mlib的本地向量有两种: DenseVctor :稠密向量 其创建方式 Vector.dense(数据) SparseVector :稀疏向量 其创建方式有两种: 方法一:Vector. ...