• [poj3261]Milk Patterns(后缀数组)


    题意:可重叠的k次最长重复子串

    解题关键:利用height数组对后缀进行分组,因为最长公共子串一定会在一个组内,所以判定每个组即可。二分答案,进行判定。

     1 #include <cstdlib>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include<iostream>
     6 #include<cmath>
     7 #define inf 0x3f3f3f3f
     8 using namespace std;
     9 const int N=200005;
    10 int wa[N],wb[N],wv[N],wc[N];
    11 bool cmp(int *r,int a,int b,int l){return r[a]==r[b]&&r[a+l]==r[b+l];}
    12 void make_sa(int *r,int *sa,int n,int m){
    13     int i,j,p,*x=wa,*y=wb;
    14     for(i=0;i<m;i++) wc[i]=0;
    15     for(i=0;i<n;i++) wc[x[i]=r[i]]++;
    16     for(i=1;i<m;i++) wc[i]+=wc[i-1];
    17     for(i=n-1;i>=0;i--) sa[--wc[x[i]]]=i;
    18     for(j=1,p=1;p<n;j*=2,m=p){
    19         for(p=0,i=n-j;i<n;i++) y[p++]=i;
    20         for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
    21         for(i=0;i<n;i++) wv[i]=x[y[i]];
    22         for(i=0;i<m;i++) wc[i]=0;
    23         for(i=0;i<n;i++) wc[wv[i]]++;
    24         for(i=1;i<m;i++) wc[i]+=wc[i-1];
    25         for(i=n-1;i>=0;i--) sa[--wc[wv[i]]]=y[i];
    26         for(swap(x,y),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++;
    27     }
    28     return;
    29 }
    30 int rank1[N],height[N],sa[N];
    31 void make_height(int *r,int *sa,int n){
    32     int i,j,k=0;
    33     for(i=1;i<=n;i++) rank1[sa[i]]=i;
    34     for(i=0;i<n;height[rank1[i++]]=k)
    35         for(k?k--:0,j=sa[rank1[i]-1];r[i+k]==r[j+k];k++);
    36     return;
    37 }
    38 
    39 int n,k,r[N]; 
    40 bool check(int x){
    41     int num=0;
    42     for(int i=2;i<=n;i++){
    43         if(height[i]>=x){
    44             num++;
    45             if(num>=k) return true;
    46         }
    47         else num=1;
    48     }
    49     return false;
    50 }
    51 
    52 int erfen(int l,int r){
    53     while(l<r){
    54         int mid=(l+r+1)>>1;
    55         if(check(mid)) l=mid;
    56         else r=mid-1;
    57     }
    58     return l;
    59 }
    60 
    61 int main(){
    62     ios::sync_with_stdio(0);
    63     int maxn=0;
    64     while(cin>>n>>k){
    65         for(int i=0;i<n;i++) cin>>r[i],maxn=max(maxn,r[i]);
    66         r[n]=0;
    67         make_sa(r, sa, n+1,maxn+1);
    68         make_height(r, sa, n);
    69         int ans=erfen(0,n);
    70         cout<<ans<<"
    ";
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    Title标题及Description描述字数
    网站优化十忌
    link和domain的区别
    什么是回合制游戏
    人文社科核心、中文核心、北大核心期刊
    锚文本
    笔记本声音尖叫的问题
    Educational Technology Journals(转)
    配置SharePoint门户网站的基本思路
    SEO 如何优化单个页面16招
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7576917.html
Copyright © 2020-2023  润新知