• BZOJ2946: [Poi2000]公共串


    2946: [Poi2000]公共串

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 55  Solved: 33
    [Submit][Status]

    Description

     
           给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
    任务:
    l        读入单词
    l        计算最长公共子串的长度
    l        输出结果
     

    Input

     
    文件的第一行是整数 n1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000
     

    Output

    仅一行,一个整数,最长公共子串的长度。
     

    Sample Input

    3
    abcb
    bca
    acbc

    Sample Output

    题解:
    后缀数组经典做法。
    代码:
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 100000
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 int n,m,c[maxn],t1[maxn],t2[maxn],sa[maxn],rk[maxn],h[maxn],a[maxn];
    32 char s[maxn];
    33 bool v[10];
    34 void getsa(int m)
    35 {
    36     int *x=t1,*y=t2;
    37     for0(i,m)c[i]=0;
    38     for0(i,n)c[x[i]=s[i]]++;
    39     for1(i,m)c[i]+=c[i-1];
    40     for3(i,n,0)sa[--c[x[i]]]=i;
    41     for(int k=1;k<=n+1;k<<=1)
    42     {
    43         int p=0;
    44         for2(i,n-k+1,n)y[p++]=i;
    45         for0(i,n)if(sa[i]>=k)y[p++]=sa[i]-k;
    46         for0(i,m)c[i]=0;
    47         for0(i,n)c[x[y[i]]]++;
    48         for1(i,m)c[i]+=c[i-1];
    49         for3(i,n,0)sa[--c[x[y[i]]]]=y[i];
    50         swap(x,y);p=0;x[sa[0]]=0;
    51         for1(i,n)x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p;
    52         if(p>=n)break;
    53         m=p;
    54     }
    55     for1(i,n)rk[sa[i]]=i;
    56     for(int i=0,k=0,j;i<n;h[rk[i++]]=k)
    57      for(k?k--:0,j=sa[rk[i]-1];s[i+k]==s[j+k];k++);
    58 }    
    59 bool check(int x)
    60 {
    61     for(int i=1,j=1;j<=n+1;j++)
    62      if(h[j]<x||j==n+1)
    63       {
    64           for1(k,m)v[k]=0;
    65           for2(k,i,j-1)v[a[sa[k]]]=1;
    66           bool flag=0;
    67           for1(k,m)if(!v[k])flag=1;
    68           if(!flag)return 1;
    69           i=j;
    70       }
    71     return 0;
    72 }
    73 int main()
    74 {
    75     freopen("input.txt","r",stdin);
    76     freopen("output.txt","w",stdout);
    77     m=read();
    78     for1(i,m)
    79     {
    80         s[n]='z'+i;
    81         scanf("%s",s+n+1);
    82         int t=strlen(s);for2(j,n+1,t-1)a[j]=i;
    83         n=t;
    84     }
    85     s[n]=' ';
    86     getsa(128);
    87     int l=0,r=n,mid;
    88     while(l<=r)
    89     {
    90         mid=(l+r)>>1;
    91         if(check(mid))l=mid+1;else r=mid-1;
    92     }
    93     printf("%d
    ",r);
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    C#利用反射动态调用类及方法
    系统程序监控软件
    SQL server 2008 安装和远程访问的问题
    sql server 创建临时表
    IIS 时间问题
    windows 2008 安装 sql server 2008
    sql server xml nodes 的使用
    Window 7sp1 安装vs2010 sp1 打开xaml文件崩溃
    CSS资源网址
    Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, Version=3.0.0.0
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4161660.html
Copyright © 2020-2023  润新知