【POJ No. 1743】音乐主题 Musical Theme

北大OJ 题目地址

【题意】音乐旋律被表示为N (1≤N ≤20000)个音符的序列,它们是[1, 88]内的整数,每个音符都代表钢琴上的一个键。许多作曲家都围绕一个重复的主题谱写音乐,该主题属于整个旋律的子序列。旋律的子序列是一个主题,若满足至少5个音符而且在音乐片段的其他地方再次出现(不重叠,但可能存在转换,转换是指该子序列中的每个音符都同时加上或减去一个值),则给定一个旋律,计算最长主题的长度(音符数)。

【输入输出】

输入:

输入包含多个测试用例,每个测试用例的第1行都包含整数N 。以下N 个整数表示音符序列。最后一个测试用例后跟一个0。

输出:

对每个测试用例,都单行输出最长主题的长度。若没有主题,则输出0。

【样例】

【思路分析】

这道题求解的是不重叠、长度大于或等于5的最长重复子串的长度,可以先转变为子串问题,再采用后缀数组及二分法求解。

因为主题子序列可能同时加上或减去一个数,如34 30 26 22 18,若同时加上48,则转换为82 78 74 70 66,因此可以将数字序列逐项求差,转变为普通的子串问题。在差值序列上求解不重叠、长度大于或等于4的最长重复子串的长度ans,因为求差序列比原序列长度少1,所以需要输出ans+1。

例如,对输入样例数据逐项求差后(从第2个开始,每个数都减去前一个数),序列如下:

不重叠长度大于或等于4的最长重复子串为-4-4-4-4,其长度为4,原序列是34 30 26 22 18,长度为5。

【算法设计】

① 逐项求差,将问题转变为普通的求子串问题。

② 求解sa数组。

③ 求解rank数组和height数组。

④ 使用二分法求解,对特定的长度mid,判断是否满足height[i ]≥mid,且sa的最大、最小差值也大于或等于mid(保证不重叠)。

【算法实现】

#include<cstdio>
#include<algorithm>using namespace std;const int maxn=20010;
const int maxm=200;
int n,k;
int s[maxn],ss[maxn],sa[maxn],rank[maxn],height[maxn];;
int wa[maxn],wb[maxn],wv[maxn],c[maxm];int cmp(int *r,int a,int b,int l){return r[a]==r[b]&&r[a+l]==r[b+l];
}void da(int *r,int *sa,int n,int m){int i,k,p,*x=wa,*y=wb;for(i=0;i<m;i++) c[i]=0;for(i=0;i<n;i++) c[x[i]=r[i]]++;for(i=1;i<m;i++) c[i]+=c[i-1];for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;for(k=1;k<=n;k<<=1){//直接利用sa排序第二关键字 p=0;for(i=n-k;i<n;i++) y[p++]=i;//补零的位置下标排在最前面 for(i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;//基数排序第一关键字for(i=0;i<n;i++)wv[i]=x[y[i]];//将第二关键字排序结果转换为名次,进行排序 for(i=0;i<m;i++)c[i]=0;for(i=0;i<n;i++)c[wv[i]]++;for(i=1;i<m;i++)c[i]+=c[i-1];for(i=n-1;i>=0;i--)sa[--c[wv[i]]]=y[i];//根据sa和x数组,重新计算新的x数组swap(x,y);//y数组已经没有用,更新x需要使用x本身数据,因此放入y使用 p=1,x[sa[0]]=0;for(i=1;i<n;i++)x[sa[i]]=cmp(y,sa[i-1],sa[i],k)?p-1:p++;if(p>=n)//排序结束 break;m=p;}
}void calheight(int *r,int *sa,int n){int i,j,k=0;for(i=1;i<=n;i++)rank[sa[i]]=i;for(i=0;i<n;i++){if(k)k--;j=sa[rank[i]-1];while(r[i+k]==r[j+k])k++;height[rank[i]]=k;}
}bool check(int mid){int mx=sa[1],mn=sa[1];for(int i=2;i<=n;i++){if(height[i]>=mid){mx=max(mx,sa[i]);mn=min(mn,sa[i]);if(mx-mn>=mid)return 1;}   else{mx=sa[i];mn=sa[i];}}return 0;
}void solve(){int L=4,R=n,res=-1;while(L<=R){int mid=(L+R)>>1;if(check(mid)){res=mid;L=mid+1;}elseR=mid-1;}if(res<4)printf("0\n");elseprintf("%d\n",res+1);
}int main(){while(~scanf("%d",&n),n){for(int i=0;i<n;i++)scanf("%d",&s[i]);if(n<9){printf("0\n");continue;}n--;for(int i=0;i<n;i++)ss[i]=s[i+1]-s[i]+100;ss[n]=0;da(ss,sa,n+1,200);calheight(ss,sa,n);solve();}return 0;
}

【POJ No. 1743】音乐主题 Musical Theme相关推荐

  1. R语言编写自定义函数、创建使用ggplot2生成图标(icon)的主题(theme)函数、使用ggplot2以及自定义的图标主题函数创建箱图(boxplot)图标、ggsave保存图标(png、svg

    R语言编写自定义函数.创建使用ggplot2生成图标(icon)的主题(theme)函数.使用ggplot2以及自定义的图标主题函数创建箱图(boxplot)图标.ggsave保存图标(png.svg ...

  2. R语言ggplot2可视化设置不同的图像主题(theme):使用各种不同的主题(theme)可视化数据、单的黑白主题theme_bw主题(theme)、默认的主题(theme)可视化数据

    R语言ggplot2可视化设置不同的图像主题(theme):使用各种不同的主题(theme)可视化数据.单的黑白主题theme_bw主题(theme).默认的主题(theme)可视化数据 目录

  3. Musical Theme pku1743 (后缀数组)

    Musical Theme(后缀数组) 题意: n个数,选取一段子序列,满足以下条件: 1.长度至少为5 2.在数列中其他位置出现过(允许转置) 3.与其他位置出现的不重叠 转置:将恒定的正或负值添加 ...

  4. 谷歌Chrome浏览器的Mac主题 OS theme

    https://chrome.google.com/webstore/detail/jkpadlfbbnobnjaeodjfnkogiigdmgff?utm_source=google-chrome- ...

  5. The Sandbox 和华纳音乐集团达成合作,将在元宇宙建立音乐主题世界

    The Sandbox 元宇宙将更具音乐性! 准备好发现以前从未听说过的元宇宙世界了吗? The Sandbox 很高兴宣布已经与华纳音乐集团建立了合作关系,并在 The Sandbox 元宇宙中开辟 ...

  6. android 主题xml,自定义Android主题风格theme.xml方法 Android开发技术

    自定义Android主题风格theme.xml方法 Android开发技术 2013 年 5 月 23 日 在Android中可以通过自定义主题风格方式来实现个性化以及复用,首先我们创建theme.x ...

  7. Emlog主题:DJ音乐主题

    Emlog 是一款基于PHP和MySQL的功能强大的博客及CMS建站系统. 这个肯定是毋庸置疑的,但是最近我发现有人用Emlog做了一款DJ音乐主题. 总之就两个字"局气" CYP ...

  8. 精美高清壁纸:30款音乐主题壁纸免费下载

    音乐有数百种不同的类型,每个人自己都有特定喜欢的类别.音乐是一种独特的艺术形式,远不止只是从口或从乐器发出声音.在这个展示中,你会发现最好的音乐主题壁纸,相信你一定能找到喜欢的来装饰电脑桌面. 您可能 ...

  9. ggplot 主题(theme)

    ggplot 主题(theme) theme主要参数设置 参数 含义 plot.title 设置标题的位置 title 设置所有标题的格式,包括大小,粗细,颜色等,element_text() axi ...

最新文章

  1. JavaScript-学习一全局变量
  2. 如何确定线程池的大小?
  3. @SessionAttributes 和 @SessionAttribute的区别
  4. 计算机应用基础本模块一测试,广东开放大学远程教育专科2018年秋计算机应用基础Word模块测试...
  5. ansible 修改文件变量_Ansible Playbook中的变量与引用
  6. 计算机用户登录,计算机术语:密码、用户、登录
  7. 动态添加控件[可重复同一控件]
  8. BZOJ1492: [NOI2007]货币兑换Cash(CDQ分治,斜率优化动态规划)
  9. JavaScript与JSP区别
  10. (转)Inno Setup入门(十七)——Inno Setup类参考(3)
  11. Java全能手册火了!Redis/Nginx/Dubbo/Spring全家桶/高并发
  12. Hadoop基础-配置历史服务器
  13. chkconfig命令及的使用 与linux的七个运行级别
  14. 空对地(air-to-ground,A2G)通信发展概况与面临挑战
  15. mysql concat函数进行模糊查询
  16. fastadmin项目实战踩坑
  17. 计算机网络:端到端原则对互联网的影响与面临的问题
  18. Jetpack Compose 从入门到入门(七)
  19. 批量替换Excel超级链接
  20. 报考PMP证书要花多少钱

热门文章

  1. matlab求解出来的函数,变成点乘,并且成为函数
  2. 可交互的数据可视化信息展示案例、u3d智慧城市、Ventuz数据可视化、大屏数据交互可视化、数字孪生
  3. Scrum是敏捷开发中的一种形式,它提供了一系列流程、方法、工具,旨在帮助项目团队保持高效、可持续地交付价值
  4. 买笔记本,第一是质量
  5. 毕业入行测试5年,从“懵懂少年”到“甩锅老油条”,我的经验值得你的借鉴~
  6. 思科SG300,SG500,SF300,SF500系统默认VLAN解析
  7. 大数据面试题:数据倾斜解决方法
  8. python类的参数_在Python中使用类中的参数
  9. K8S-遇到问题-解决日记
  10. Docker入门之Docker Swarm