zoukankan      html  css  js  c++  java
  • PAT (Top Level) Practise 1005 Programming Pattern (35)

    后缀数组。排序之后得到height数组,然后从上到下将height>=len的都分为一组,然后找到第一组个数最多的输出即可。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-8;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    inline int read()
    {
        char c = getchar();  while(!isdigit(c)) c = getchar();
        int x = 0;
        while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
        return x;
    }
    
    const int maxn=1048576+10;
    
    int wa[maxn],wb[maxn],wv[maxn],WS[maxn];
    int cmp(int *r,int a,int b,int l)
    {
        return r[a]==r[b]&&r[a+l]==r[b+l];
    }
    void da(int *r,int *sa,int n,int m)
    {
        int i,j,p,*x=wa,*y=wb,*t;
        for(i=0; i<m; i++) WS[i]=0;
        for(i=0; i<n; i++) WS[x[i]=r[i]]++;
        for(i=1; i<m; i++) WS[i]+=WS[i-1];
        for(i=n-1; i>=0; i--) sa[--WS[x[i]]]=i;
        for(j=1,p=1; p<n; j*=2,m=p)
        {
            for(p=0,i=n-j; i<n; i++) y[p++]=i;
            for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
            for(i=0; i<n; i++) wv[i]=x[y[i]];
            for(i=0; i<m; i++) WS[i]=0;
            for(i=0; i<n; i++) WS[wv[i]]++;
            for(i=1; i<m; i++) WS[i]+=WS[i-1];
            for(i=n-1; i>=0; i--) sa[--WS[wv[i]]]=y[i];
            for(t=x,x=y,y=t,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++;
        }
        return;
    }
    
    int Rank[maxn],height[maxn];
    void calheight(int *r,int *sa,int n)
    {
        int i,j,k=0;
        for(i=1; i<=n; i++) Rank[sa[i]]=i;
        for(i=0; i<n; height[Rank[i++]]=k)
            for(k?k--:0,j=sa[Rank[i]-1]; r[i+k]==r[j+k]; k++);
        return;
    }
    
    int T,n,a[maxn],SA[maxn],sum[maxn];
    char str[maxn],op[5];
    
    int Find(int D,int l,int r)
    {
        int pos=-1;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(sum[mid]-D>1) r=mid-1;
            else if(sum[mid]-D==1) pos=mid,r=mid-1;
            else l=mid+1;
        }
        return pos;
    }
    
    int main()
    {
        int len; scanf("%d",&len); getchar();
        gets(str); n=strlen(str);
        for(int i=0;i<n;i++) a[i]=(int)str[i];
        a[n]=0; da(a,SA,n+1,300); calheight(a,SA,n);
        int L=1,R=1;
        int ansL,ansR,ans=0;
        while(1)
        {
            if(height[R]>=len)
            {
                R++;
                if(R-L+1>ans) ans=R-L+1, ansL = L, ansR = R;
            }
            else L=R+1, R=L;
            if(L>n||R>n) break;
        }
        for(int i=SA[ansL];i<=SA[ansL]+len-1;i++) printf("%c",str[i]);
        printf(" %d
    ",ans);
        return 0;
    }
  • 相关阅读:
    LeetCode 842. Split Array into Fibonacci Sequence
    LeetCode 1087. Brace Expansion
    LeetCode 1219. Path with Maximum Gold
    LeetCode 1079. Letter Tile Possibilities
    LeetCode 1049. Last Stone Weight II
    LeetCode 1046. Last Stone Weight
    LeetCode 1139. Largest 1-Bordered Square
    LeetCode 764. Largest Plus Sign
    LeetCode 1105. Filling Bookcase Shelves
    LeetCode 1027. Longest Arithmetic Sequence
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5744413.html
Copyright © 2011-2022 走看看