码迷,mamicode.com
首页 > 其他好文 > 详细

Milk Patterns(poj 3261)

时间:2017-03-12 23:23:29      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:pac   数组   code   att   ons   swa   --   ios   height   

题意:找出出现k次的可重叠的最长子串的长度。

/*
    求出height数组,二分答案,将height分组,看有没有一组个数大于K。 
    WA了很多遍,最后看别人的题解,发现往字符串后面填了一个0,就可以AC了,不知道为什么。 
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 100010
using namespace std;
int s[N],sa[N],rk[N],ht[N],t1[N],t2[N],c[N],n,K;
struct node{
    int x,id;
    bool operator<(const node&a)const{
        if(x==a.x) return id<a.id;
        return x<a.x;
    }
}r[N];
bool cmp(int *y,int a,int b,int k){
    int a1=y[a],b1=y[b];
    int a2=a+k<n?y[a+k]:-1;
    int b2=b+k<n?y[b+k]:-1;
    return a1==b1&&a2==b2;
}
void DA(){
    int *x=t1,*y=t2,m=1;n++;
    sort(r,r+n);
    for(int i=0;i<n;i++) sa[i]=r[i].id;
    x[sa[0]]=0;
    for(int i=1;i<n;i++) x[sa[i]]=(r[i].x==r[i-1].x?m-1:m++);
    for(int k=1,p=0;k<=n;k*=2,m=p,p=0){
        for(int i=n-k;i<n;i++) y[p++]=i;
        for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
        for(int i=0;i<m;i++) c[i]=0;
        for(int i=0;i<n;i++) c[x[y[i]]]++;
        for(int i=1;i<m;i++) c[i]+=c[i-1];
        for(int i=n-1;~i;i--) sa[--c[x[y[i]]]]=y[i];
        
        swap(x,y);p=1;x[sa[0]]=0;
        for(int i=1;i<n;i++)
            if(cmp(y,sa[i-1],sa[i],k)) x[sa[i]]=p-1;
            else x[sa[i]]=p++;
        if(p>=n) break;
    }
    for(int i=0;i<n;i++) rk[sa[i]]=i;n--;
}
void get_ht(){
    for(int i=0,k=0;i<n;ht[rk[i++]]=k){
        int j=sa[rk[i]-1];k=k?k-1:0;
        while(s[i+k]==s[j+k]) k++;
    }
}
bool check(int mid){
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(ht[i]<mid) cnt=1;
        else cnt++;
        if(cnt>=K) return true;
    }
    return false;
}
int main(){
    while(scanf("%d%d",&n,&K)!=EOF){
        for(int i=0;i<n;i++) {
            scanf("%d",&s[i]);
            r[i].x=s[i]+1;r[i].id=i;
        }
        r[n].x=0,r[n].id=n;
        DA();get_ht();
        int l=0,r=n,ans;
        while(l<=r){
            int mid=l+r>>1;
            if(check(mid)) ans=mid,l=mid+1;
            else r=mid-1;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

Milk Patterns(poj 3261)

标签:pac   数组   code   att   ons   swa   --   ios   height   

原文地址:http://www.cnblogs.com/harden/p/6539717.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!