zoukankan      html  css  js  c++  java
  • [Poj3261] [Bzoj1717] [后缀数组论文例题,USACO 2006 December Gold] Milk Patterns [后缀数组可重叠的k次最长重复子串]

    和上一题(POJ1743,上一篇博客)相似,只是二分的判断条件是:是否存在一段后缀的个数不小于k

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cmath>
     7 #include <ctime>
     8 #include <map>
     9 
    10 using namespace std;
    11 
    12 int    t;
    13 int    str[21000],A[21000],B[21000],U[21000],Tmp[21000],SA[21000],H[21000];
    14 map <int,int>    Map;
    15 
    16 void    Calc_H(const int n,const int * Rank)
    17 {
    18     int    i,j,k=0;
    19     for(i=0;i<n;H[Rank[i++]]=k)
    20         for(k?k--:0,j=SA[Rank[i]-1];str[i+k]==str[j+k];++k);
    21     return ;
    22 }
    23 
    24 bool    cmp(const int * s,const int a,const int b,const int l)
    25 {
    26     return s[a]==s[b] && s[a+l]==s[b+l];
    27 }
    28 
    29 int*    Get_SA(const int n,int    m)
    30 {
    31     int    i,j,p,*x=A,*y=B;
    32 
    33     for(i=0;i<n;++i)U[i]=0;
    34     for(i=0;i<n;++i)U[x[i]=str[i]]++;
    35     for(i=1;i<m;++i)U[i]+=U[i-1];
    36     for(i=n-1;i>=0;--i)SA[--U[x[i]]]=i;
    37 
    38     for(j=1,p=1;p<n;j<<=1,m=p)
    39     {
    40         for(p=0,i=n-j;i<n;++i)y[p++]=i;
    41         for(i=0;i<n;++i)if(SA[i]>=j)y[p++]=SA[i]-j;
    42         for(i=0;i<n;++i)Tmp[i]=x[y[i]];
    43         for(i=0;i<m;++i)U[i]=0;
    44         for(i=0;i<n;++i)U[Tmp[i]]++;
    45         for(i=1;i<m;++i)U[i]+=U[i-1];
    46         for(i=n-1;i>=0;--i)SA[--U[Tmp[i]]]=y[i];
    47         for(swap(x,y),p=1,x[SA[0]]=0,i=1;i<n;++i)
    48         x[SA[i]]=cmp(y,SA[i-1],SA[i],j)?p-1:p++;
    49     }
    50 
    51     Calc_H(n,x);
    52     return x;
    53 }
    54 
    55 bool    Check(const int lim,const int n)
    56 {
    57     int    cnt=0;
    58     for(int i=1;i<=n;++i)
    59     {
    60         if(i>1 && H[i]<lim)
    61         {
    62             if(cnt>=t)return true;
    63             cnt=1;
    64         }
    65         if(H[i]>=lim)cnt++;
    66     }
    67     if(cnt>=t)return true;
    68     return false;
    69 }
    70 
    71 int main()
    72 {
    73     int    i,l,r,n,cnt=0;
    74 
    75     scanf("%d%d",&n,&t);
    76     for(i=0;i<n;++i)
    77     {
    78         scanf("%d",&str[i]);
    79         if(!Map[str[i]])Map[str[i]]=++cnt;
    80         str[i]=Map[str[i]];
    81     }
    82 
    83     Get_SA(n+1,21000);
    84 
    85     l=0;r=n;
    86     while(l<r-1)
    87     {
    88         int    mid=l+((r-l)>>1);
    89         if(Check(mid,n))l=mid;
    90         else    r=mid;
    91     }
    92 
    93     printf("%d
    ",l);
    94 
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    codeforces 980A Links and Pearls
    zoj 3640 Help Me Escape
    sgu 495 Kids and Prizes
    poj 3071 Football
    hdu 3853 LOOPS
    hdu 4035 Maze
    hdu 4405 Aeroplane chess
    poj 2096 Collecting Bugs
    scu 4444 Travel
    zoj 3870 Team Formation
  • 原文地址:https://www.cnblogs.com/Gster/p/4977968.html
Copyright © 2011-2022 走看看