zoukankan      html  css  js  c++  java
  • uva12206 后缀数组

    这题说的是给了一串字符 我们要将这个字符 中找出至少出现m次的最长字符串 一个字符课多次使用

    利用后缀数组计算最长的lcp 

    这里有一个点 记得将后缀数组中加入一个空串 如果遇到全部相同的字符时 没办法 判断 倒数第二个和 第三个的大小 因此他们就会被遗漏 

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #include <string.h>
    using namespace std;
    const int maxn =100005;
    struct SuffixArray
    {
         int s[maxn];
         int sa[maxn];
         int t[maxn],t2[maxn],c[maxn];
         int rank[maxn],lcp[maxn];
         int n;
         void build(int m)
         {
    
             int *x=t,*y=t2,i;
             for(i=0; i<m; i++ )c[i]=0;
             for(i=0; i<n; i++)c[ x[i]=s[i]  ]++;
             for(i=1; i<m; i++)c[i]+=c[i-1];
             for(i=n-1; i>=0; i--)sa[ --c[ x[i]  ]   ]=i;
             for(int k=1; k<=n; k<<=1)
                {
                    int p=0;
                     for(i=n-k; i<n; i++) y[ p++ ]=i;
                     for(i=0; i<n; i++)if(sa[i]>=k) y[p++ ]= sa[i]-k;
                     for(i=0; i<m; i++) c[ i ]=0;
                     for(i=0; i<n; i++) c[ x[ y[i] ]  ]++;
                     for(i=1; i<m; i++)c[i]+=c[i-1];
                     for(i=n-1; i>=0; i--)
                        sa[ -- c[ x[ y[ i ] ] ]   ]=y[i];
                     for(i=0; i<n; i++)rank[ sa[i] ]=i;
                     p=1;
                     swap(x,y);
                      x[ sa[0] ] =0;
                     for(int i=1; i<n; i++)
                        x[ sa[i]  ]= y[ sa[i] ]==y[ sa[i-1] ]&&y[ sa[i]+k ]==y[ sa[i-1]+k  ] ?p-1:p++;
                     if(p>=n)break;
                     m=p;
                }
         }
         void getLcp()
         {
              int i,k=0;
              for(i=0; i<n; i++)rank[ sa[ i ] ] =i;
              for(i=0; i<n; i++)
                {
                    if(k)k--;
                    int j=sa[ rank[i]-1  ];
                    while(s[j+k]==s[i+k])k++;
                    lcp[ rank[i]  ]=k;
                }
         }
    }sa;
    bool solve(int len,int m)
    {
         int L=0;
         for(int R=1; R<=sa.n; R++)
         {
             if(sa.lcp[R]<len||R==sa.n)
                {
                    if( R-L >= m )return true;
                    L=R;
                }
    
         }
         return false;
    }
    int look(int L, int R)
    {
          int ans=-1;
          for(int i=L; i<R; i++)
            {
                 ans=max(sa.sa[i],ans);
            }
          return ans;
    }
    
    int select(int len, int m)
    {
         int L=0,ad=-1;
    
         for(int R=1; R<=sa.n; R++)
         {
             if(sa.lcp[R]<len||R==sa.n)
                {
                    if(R-L>=m)
                        {
                            ad=max(look(L,R),ad);
                        }
    
                       L=R;
                }
    
         }
         return ad;
    }
    char ss[maxn];
    int main()
    {
        int m;
        while(scanf("%d",&m)==1)
        {
    
             if(m==0)break;
            scanf("%s",ss);
    
            sa.n=strlen(ss);
            for(int i=0; i<sa.n; i++)
                {
                     sa.s[i]= ss[i]-'a'+1;
                }
            if(m==1)
                {
                   printf("%d %d
    ",sa.n,0); continue;
                }
            sa.s[sa.n]=0;
            sa.n++;
            sa.build(27);
            sa.getLcp();
    
            if(solve(1,m)==false)
                {
                    puts("none");continue;
                }
            int L=1,R=sa.n,ans;
            while(L<=R)
                {
                   int mid=(R+L)/2;
                    if(solve(mid,m)){
                        ans=mid; L=mid+1;
                    }else R=mid-1;
                }
            printf("%d %d
    ",ans,select(ans,m));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    我眼中的DevOps
    Jenkins常用插件介绍之权限控制插件Role-based Authorization Strategy
    sql查询一个班级中总共有多少人以及男女分别多少人
    win8 图片等路径
    WPF 设置TextBox为空时,背景为文字提示。
    WCF服务发布
    win8 摄像
    oracle 删除主键
    oracle 数据库连接
    oracle 创建用户表
  • 原文地址:https://www.cnblogs.com/Opaser/p/4504500.html
Copyright © 2011-2022 走看看