• poj_1743_Musical Theme(后缀数组)


    题目链接:poj_1743_Musical Theme

    题意:

    给你一串数字,让你找最长的变化相同不重叠的子串,至少长度为5

    题解:

    处理数据后用后缀数组加二分答案,然后用height数组check答案,运用height数组求相同不重叠的子串经典运用

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define F(i,a,b) for(int i=a;i<=b;i++)
     4 using namespace std;
     5 
     6 namespace suffixarray{    
     7     #define FN(n) for(int i=0;i<n;i++)
     8     const int N =2E4+7;
     9     int rnk[N],sa[N],height[N],c[N],s[N];
    10     void getsa(int n,int m,int *x=rnk,int *y=height){
    11         FN(m)c[i]=0;FN(n)c[x[i]=s[i]]++;FN(m)c[i+1]+=c[i];
    12         for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
    13         for(int k=1,p;p=0,k<=n;k=p>=n?N:k<<1,m=p){
    14             for(int i=n-k;i<n;i++)y[p++]=i;
    15             FN(n)if(sa[i]>=k)y[p++]=sa[i]-k;
    16             FN(m)c[i]=0;FN(n)c[x[y[i]]]++;FN(m)c[i+1]+=c[i];
    17             for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
    18             swap(x,y),p=1,x[sa[0]]=0;
    19             for(int i=1;i<n;i++)
    20             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
    21         }
    22         FN(n)rnk[sa[i]]=i;
    23         for(int i=0,j,k=0;i<n-1;height[rnk[i++]]=k)
    24         for(k=k?k-1:k,j=sa[rnk[i]-1];s[i+k]==s[j+k];k++);
    25     }
    26 }
    27 
    28 using namespace suffixarray;
    29 int n;
    30 inline void upd(int &a,int b){if(a>b)a=b;}
    31 inline void upu(int &a,int b){if(a<b)a=b;}
    32 
    33 inline bool check(int x)
    34 {
    35     int l=N,r=0;
    36     F(i,1,n)
    37     {
    38         if(height[i]>=x)
    39         {
    40             upd(l,sa[i]),upu(r,sa[i]);
    41             if(r-l>=x)return 1;
    42         }else l=r=sa[i];
    43     }
    44     return 0;
    45 }
    46 
    47 int main()
    48 {
    49     while(scanf("%d",&n),n)
    50     {
    51         F(i,0,n-1)scanf("%d",s+i);
    52         if(n<10){puts("0");continue;}
    53         F(i,0,n-2)s[i]=s[i+1]-s[i]+89;
    54         s[--n]=0,getsa(n+1,200);
    55         int l=4,r=n,mid;
    56         while(l<=r)mid=(l+r)>>1,check(mid)?l=mid+1:r=mid-1;
    57         printf("%d
    ",l<5?0:l);
    58     }
    59     return 0;
    60 }
    View Code
  • 相关阅读:
    SPOJ 8093 JZPGYZ
    UVA1030 Image Is Everything
    UVA11996 Jewel Magic
    UVA11922 Permutation Transformer
    UVA1479 Graph and Queries
    P3224 [HNOI2012]永无乡
    UVA11020 Efficient Solutions
    UVA12206 Stammering Aliens
    UVA11107 Life Forms
    UVA11019 Matrix Matcher
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5766519.html
Copyright © 2020-2023  润新知