POJ 1743 Musical Theme

来源:互联网 发布:软件测试书籍电子版 编辑:程序博客网 时间:2024/05/21 09:03

Description

A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the range 1..88, each representing a key on the piano. It is unfortunate but true that this representation of melodies ignores the notion of musical timing; but, this programming task is about notes and not timings.
Many composers structure their music around a repeating &qout;theme&qout;, which, being a subsequence of an entire melody, is a sequence of integers in our representation. A subsequence of a melody is a theme if it:
is at least five notes long
appears (potentially transposed – see below) again somewhere else in the piece of music
is disjoint from (i.e., non-overlapping with) at least one of its other appearance(s)

Transposed means that a constant positive or negative value is added to every note value in the theme subsequence.
Given a melody, compute the length (number of notes) of the longest theme.
One second time limit for this problem’s solutions!


【题目分析】
后缀数组+二分最优转判定 思路简直不要太好。由于有转调(同时加上或者减去一个值)只能记录下变化量,输出的时候再加上一。注意的是,最终结果小于4要输出量。
复制的题解如下

先二分答案,把题目变成判定性问题:判断是否存在两个长度为k的子串是相同的,且不重叠。解决这个问题的关键还是利用height数组。把排序后的后缀分成若干组,其中每组的后缀之间的height值都不小于k。容易看出,有希望成为最长公共前缀不小于k的两个后缀一定在同一组。然后对于每组后缀,只须判断每个后缀的sa值的最大值和最小值之差是否不小于k。如果有一组满足,则说明存在,否则不存在。整个做法的时间复杂度为O(nlogn)。
思路太好,写起来水道渠成,然后WA。最后加了小于5的判断才过。


【代码】

#include <cstring>#include <cstdio>#define maxn 20001#define m(a) memset(a,0,sizeof a)int wa[maxn],wb[maxn],wv[maxn],ws[maxn],sa[maxn],rank[maxn],height[maxn],s[maxn],n,a[maxn];inline int cmp(int *r,int a,int b,int l){return r[a]==r[b]&&r[a+l]==r[b+l];}inline void getsa(int *r,int *sa,int n,int m){    int i,j,p,*x=wa,*y=wb,*t;    for (i=0;i<m;++i) ws[i]=0;    for (i=0;i<n;++i) ws[x[i]=r[i]]++;    for (i=1;i<m;++i) ws[i]+=ws[i-1];    for (i=n-1;i>=0;--i) sa[--ws[x[i]]]=i;    for (j=1,p=1;p<n;j*=2,m=p)    {        for (p=0,i=n-j;i<n;++i) y[p++]=i;        for (i=0;i<n;++i) if (sa[i]>=j) y[p++]=sa[i]-j;        for (i=0;i<n;++i) wv[i]=x[y[i]];        for (i=0;i<m;++i) ws[i]=0;        for (i=0;i<n;++i) ws[wv[i]]++;        for (i=1;i<m;++i) ws[i]+=ws[i-1];        for (i=n-1;i>=0;--i) sa[--ws[wv[i]]]=y[i];        for (t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;++i)        x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;    }}inline void gethi(int *r,int n){    int i,j,k=0;    for (i=1;i<=n;++i) rank[sa[i]]=i;    for (i=0;i<n;height[rank[i++]]=k)        for (k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);}inline int min(int a,int b){return a>b?b:a;}inline int max(int a,int b){return a>b?a:b;}inline bool test(int k){    int minn=0x3f3f3f3f,maxx=-0x3f3f3f3f;    int i=2;    while (i<=n)    {        if (height[i]>=k)        {            minn=min(minn,sa[i-1]),maxx=max(maxx,sa[i-1]);            while (height[i+1]>=k) ++i,minn=min(minn,sa[i-1]),maxx=max(maxx,sa[i-1]);            minn=min(minn,sa[i]),maxx=max(maxx,sa[i]);            if (maxx-minn>=k) return true;        }        minn=0x3f3f3f3f,maxx=-0x3f3f3f3f;        i++;    }    return false;}int main(){    while (scanf("%d",&n)&&n)    {        for (int i=0;i<n;++i) scanf("%d",&a[i]); if (n<10){printf("0\n");continue;}        for (int i=0;i<n-1;++i) s[i]=a[i+1]-a[i]+89;        n--;        s[n]=0;        getsa(s,sa,n+1,200);        gethi(s,n);        int l=4,r=(n-1)/2;        while (l<r)        {            int mid=(l+r+1)/2;            if (test(mid)) l=mid;            else r=mid-1;        }        printf("%d\n",l<4?0:l+1);    }}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝卖家被投诉盗图怎么办 淘宝卖家被投诉卖假货怎么办 淘宝买到假货卖家不承认怎么办 被投诉盗图扣2分怎么办 拼多多盗淘宝图怎么办 微信视频清理了怎么办 牛仔短裤买大了怎么办 淘宝图片打开变大了怎么办 同城换公司社保怎么办 劳务不给交社保怎么办 好多工厂外包工不交社保怎么办 外包公司没有交社保怎么办 外包公司不给交社保怎么办 银行取100万现金怎么办 给老外发警告信后怎么办 照片上传是歪的怎么办 日亚不能直邮的怎么办 电话信息被卖了怎么办 被亚马逊跟卖了怎么办 玉米出芽后土壤不够湿怎么办 雨伞请输入授权码怎么办 网页放手机端后看不了怎么办 微信收款码存在违法行为怎么办 tst优惠码密码忘了怎么办 扩展器登录不上怎么办 微信学法小程序积分不更新怎么办 开发商不给办房产证怎么办 传淘宝产品规格不匹配怎么办 刚买的手机想退怎么办 空调主机空间不足不散热怎么办 lol网速快延迟高怎么办 4g手机延迟高怎么办 天气冷鼻炎就犯怎么办 天气冷宝宝发烧了怎么办 wp手机开机忘记了密码怎么办 微商退货不退款怎么办 微商退货了不退款怎么办 微商退货后不退款怎么办 有赞买东西付款没发货怎么办 赞礼号掉了东西怎么办 万达贷系统维护还不了款怎么办