zoukankan      html  css  js  c++  java
  • POJ1226 Substrings

    后缀数组。

    求多个字符串翻转与否中最长公共子串长。

    二分答案,反过来多建一倍的字符串,二分时特判一下即可。

    By:大奕哥

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<iostream>
     6 #define rank fank
     7 using namespace std;
     8 const int N=1000005;
     9 int r[N],wa[N],wb[N],wv[N],wu[N],sa[N],rank[N],height[N],bel[N],cnt;
    10 int cmp(int *r,int a,int b,int l)
    11 {
    12     return r[a]==r[b]&&r[a+l]==r[b+l];
    13 }
    14 void da(int *r,int *sa,int n,int m)
    15 {
    16     int i,j,p;int *x=wa,*y=wb;
    17     for(i=0;i<m;++i)wu[i]=0;
    18     for(i=0;i<n;++i)wu[x[i]=r[i]]++;
    19     for(i=1;i<m;++i)wu[i]+=wu[i-1];
    20     for(i=n-1;i>=0;--i)sa[--wu[x[i]]]=i;
    21     for(j=1,p=1;p<n;j<<=1,m=p)
    22     {
    23         for(p=0,i=n-j;i<n;++i)y[p++]=i;
    24         for(i=0;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j;
    25         for(i=0;i<n;++i)wv[i]=x[y[i]];
    26         for(i=0;i<m;++i)wu[i]=0;
    27         for(i=0;i<n;++i)wu[wv[i]]++;
    28         for(i=0;i<m;++i)wu[i]+=wu[i-1];
    29         for(i=n-1;i>=0;--i)sa[--wu[wv[i]]]=y[i];
    30         for(swap(x,y),p=1,x[sa[0]]=0,i=1;i<n;++i)
    31         x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    32     }
    33     return;
    34 }
    35 void calcHeight(int *rank,int *sa,int n)
    36 {
    37     int i,j,k=0;
    38     for(i=1;i<=n;++i)rank[sa[i]]=i;
    39     for(i=0;i<n;height[rank[i++]]=k)
    40         for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];++k);
    41     return ;
    42 }
    43 char s[1005];
    44 bool v[1005];
    45 int tot,num;
    46 bool check(int x,int n)
    47 {
    48     cnt=0;memset(v,0,sizeof(v));
    49     for(int i=1;i<=n;++i)
    50     {
    51         if(height[i]<x){cnt=0;memset(v,0,sizeof(v));}
    52         else
    53         {
    54             if(v[bel[sa[i-1]]]==0)cnt++,v[bel[sa[i-1]]]=1;
    55             if(!v[bel[sa[i]]])cnt++,v[bel[sa[i]]]=1;
    56             if(cnt>=num)return 1;
    57         }
    58     }
    59     return 0;
    60 }
    61 int main()
    62 {
    63     int t;
    64     scanf("%d",&t);
    65     while(t--)
    66     {
    67     scanf("%d",&num);
    68     int len=0;int p=0;
    69     for(int i=0;i<num;++i)
    70     {
    71         scanf("%s",s);
    72         int n=strlen(s);
    73         for(int j=0;j<n;++j)
    74         {
    75             r[len]=s[j];bel[len]=i;++len;
    76         } 
    77         r[len]=200+p;bel[len]=200+p;++len;++p;
    78         for(int j=n-1;j>=0;--j)
    79         {
    80             r[len]=s[j];bel[len]=i;++len;
    81         }
    82         r[len]=200+p;bel[len]=200+p;++len;++p;
    83     }
    84     --len;r[len]=0;
    85     da(r,sa,len+1,1000);
    86     calcHeight(rank,sa,len);
    87     int ans=0,l=1,r=len;
    88     while(l<=r)
    89     {
    90         int mid=l+r>>1;
    91         if(check(mid,len))ans=mid,l=mid+1;
    92         else r=mid-1;
    93     }
    94     printf("%d
    ",ans);
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    如何配置QuickFIX/N
    QuickFIX/N 动态存储配置信息
    Java深入
    【转】VS项目属性的一些配置项的总结
    vs2013中项目依赖项的作用
    Caffe初试(一)win7_64bit+VS2013+Opencv2.4.10+CUDA6.5配置Caffe环境
    【转】字符集和字符编码(Charset & Encoding)
    【转】编程思想之正则表达式
    【转】编程思想之异常处理
    【转】深入Windows内核——C++中的消息机制
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8206490.html
Copyright © 2011-2022 走看看