zoukankan      html  css  js  c++  java
  • POJ3450 Corporate Identity

    后缀数组。

    解决多个字符串的最长公共子串。

    采用对长度的二分,将子串按height分组,每次判断是否在每个字符串中都出现过。

    复杂度O(NlogN)

    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[N],ans[N];
     44 bool v[4005];
     45 int tot,num;
     46 bool check(int x,int n)
     47 {
     48     memset(v,0,sizeof(v));
     49     for(int i=2;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){
     55                 cnt++;v[bel[sa[i-1]]]=1;
     56             }
     57             if(v[bel[sa[i]]]==0){
     58                 cnt++;v[bel[sa[i]]]=1;
     59             }
     60             if(cnt==num)
     61             {
     62                 for(int j=0;j<x;++j)
     63                 ans[j]=r[sa[i]+j];
     64                 ans[x]='';
     65                 return 1;
     66             }
     67         }
     68     }
     69     return 0;
     70 }
     71 int main()
     72 {
     73     while(~scanf("%d",&num)&&num)
     74     {
     75     int len=0;
     76     for(int i=0;i<num;++i)
     77     {
     78         scanf("%s",s);
     79         int n=strlen(s);
     80         for(int j=0;j<n;++j)
     81         {
     82             r[len]=s[j];bel[len]=i;++len; 
     83         } 
     84         r[len]=200+i;bel[len]=200+i;++len;
     85     }
     86     --len;r[len]=0;
     87     da(r,sa,len+1,5000);
     88     calcHeight(rank,sa,len);
     89     int as=0,l=1,r=len;
     90     while(l<=r)
     91     {
     92         int mid=l+r>>1;
     93         if(check(mid,len))as=1,l=mid+1;
     94         else r=mid-1;
     95     }
     96     if(as)printf("%s
    ",ans);
     97     else
     98     printf("IDENTITY LOST
    ");
     99     }
    100     return 0;
    101 }

    Ps:wa了好多遍,因为插进去的ascII码值没有选好,附一张ascII表。

  • 相关阅读:
    thinkphp redis实现文章点赞功能并同步入mysql
    phpstorm2020.1最新版永久破解
    mysql修改sql_mode为宽松模式
    用为知发布博客到博客园、使用Wiz编写和发布博客园(cnblogs)博客
    Vim命令大全
    Vim教程
    GDB教程详解
    TCMalloc 对MYSQL 性能 优化的分析
    TCMalloc 安装和使用
    使用Tcmalloc进行堆栈分析
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8206161.html
Copyright © 2011-2022 走看看