• POJ 1743 Musical Theme


    题目

    给n个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等。

    Input
    The input contains several test cases. The first line of each test case contains the integer N. The following n integers represent the sequence of notes.
    The last test case is followed by one zero.
    Output
    For each test case, the output file should contain a single line with a single integer that represents the length of the longest theme. If there are no themes, output 0.
    Sample Input
    30
    25 27 30 34 39 45 52 60 69 79 69 60 52 45 39 34 30 26 22 18
    82 78 74 70 66 67 64 60 65 80
    0
    Sample Output
    5
    不考虑相似的定义,先考虑相同
    不可重叠最长重复子串
    先求出h数组,二分答案k
    然后分成若干组,每组的h都大于k,如果该区间内Max_SA-Min_SA>=k
    就说明存在长为k的不可重叠最长重复子串
    本题从相同变成"相似"
    其实把原数组差分,这样得出的新串如果有两个长度为n的子串相同,那么它们对应在原串的长度n+1的子串也就相似
    也就转化为求差分数组不可"相交"最长重复子串
    即两个子串至少要隔一个数
    因为如果两个子串靠在一起这样反应到原串那两个子串各自的首尾是重合的
    记得h[i]在最后加一个0,不然最后一组不会统计
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 using namespace std;
      7 int s[200001],c[200001],SA[200001],h[200001],n,m,x[200001],y[200001],rank[200001],Max,Min,ans;
      8 void radix_sort()
      9 {int i;
     10   for (i=0;i<m;i++)
     11     c[i]=0;
     12   for (i=0;i<n;i++)
     13     c[x[y[i]]]++;
     14   for (i=1;i<m;i++)
     15     c[i]+=c[i-1];
     16   for (i=n-1;i>=0;i--)
     17     SA[--c[x[y[i]]]]=y[i];
     18 }
     19 void build_SA()
     20 {int i,j,k,p;
     21   for (i=0;i<n;i++)
     22     x[i]=s[i],y[i]=i;
     23   m=1000;
     24   radix_sort();
     25   for (k=1;k<=n;k<<=1)
     26     {
     27       p=0;
     28       for (i=n-k;i<n;i++)
     29     y[p++]=i;
     30       for (i=0;i<n;i++)
     31     if (SA[i]>=k) y[p++]=SA[i]-k;
     32       radix_sort();
     33       p=1;swap(x,y);
     34       x[SA[0]]=0;
     35       for (i=1;i<n;i++)
     36     x[SA[i]]=((y[SA[i]]==y[SA[i-1]])&&((SA[i]+k<n?y[SA[i]+k]:-1)==(SA[i-1]+k<n?y[SA[i-1]+k]:-1)))?p-1:p++;
     37       if (p>=n) break;
     38       m=p;
     39     }
     40   for (i=0;i<n;i++)
     41     rank[SA[i]]=i;
     42   int L=0;
     43   for (i=0;i<n;i++)
     44     if (rank[i]>0)
     45       {
     46     if (L>0) L--;
     47     j=SA[rank[i]-1];
     48     while (i+L<n&&j+L<n&&(s[j+L]==s[i+L])) L++;
     49     h[rank[i]]=L;
     50       }
     51 }
     52 bool check(int mid)
     53 {int i;
     54   Max=-1e9;Min=1e9;
     55   h[n]=0;
     56   for (i=1;i<=n;i++)
     57     {
     58       if (h[i]>=mid)
     59     {
     60       Max=max(max(SA[i],SA[i-1]),Max);
     61       Min=min(min(SA[i],SA[i-1]),Min);
     62     }
     63       else
     64     {
     65       if (Max-Min>mid)
     66         return 1;
     67       Max=-1e9;Min=1e9;
     68     }
     69     }
     70   return 0;
     71 }
     72 int main()
     73 {int i,now,last;
     74   while (cin>>n&&n)
     75     {
     76       scanf("%d",&last);
     77       if (n==1)
     78     {
     79       cout<<0<<endl;
     80       continue;
     81     }
     82       for (i=0;i<n-1;i++)
     83     {
     84       scanf("%d",&now);
     85       s[i]=now-last+88;
     86       last=now;
     87     }
     88       n--;
     89       s[n]=0;
     90       build_SA();
     91       int l=0,r=n/2;
     92       ans=0;
     93       while (l<=r)
     94     {
     95       int mid=(l+r+1)/2;
     96       if (check(mid)) ans=mid,l=mid+1;
     97       else r=mid-1;
     98     }
     99       if (ans<4) printf("0
    ");
    100       else 
    101       printf("%d
    ",ans+1);
    102     }
    103 }
  • 相关阅读:
    JHipster
    Integrating Jenkins and Apache Tomcat for Continuous Deployment
    What is the difference between apache tomcat deployer and core version?
    JEECG--去掉(增加)登陆页面验证码功能
    Protobuf一例
    进程间通信之POSIX信号量
    进程间通信之共享存储
    进程间通信之信号量
    进程间通信之消息队列
    进程间通信之XSI IPC
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8479292.html
Copyright © 2020-2023  润新知