zoukankan      html  css  js  c++  java
  • POJ2774 Long Long Message 后缀数组

      题目链接:http://poj.org/problem?id=2774

      两个字符串的最长公共字串。

      求出height数组后直接二分答案就可以了,或者线性扫描一遍。

      1 //STATUS:C++_AC_594MS_4800KB
      2 #include<stdio.h>
      3 #include<stdlib.h>
      4 #include<string.h>
      5 #include<math.h>
      6 #include<iostream>
      7 #include<string>
      8 #include<algorithm>
      9 #include<vector>
     10 #include<queue>
     11 #include<stack>
     12 #include<map>
     13 using namespace std;
     14 #define LL __int64
     15 #define pii pair<int,int>
     16 #define mem(a,b) memset(a,b,sizeof(a))
     17 #define lson l,mid,rt<<1
     18 #define rson mid+1,r,rt<<1|1
     19 #define PI acos(-1.0)
     20 const int N=200010,INF=0x3f3f3f3f,MOD=10000,STA=8000010;
     21 //const LL LNF=0x3f3f3f3f3f3f3f3f;
     22 const double DNF=1e13;
     23 //
     24 inline int Max(int a,int b){return a>b?a:b;}
     25 inline int Min(int a,int b){return a<b?a:b;}
     26 void swap(int& a,int& b){int t=a;a=b;b=t;}
     27 void swap(LL& a,LL& b){LL t=a;a=b;b=t;}
     28 //
     29 
     30 char s[N/2];
     31 int num[N];
     32 int sa[N],t1[N],t2[N],c[N],rank[N],height[N];
     33 int n,m,len1,len2;
     34 
     35 void build_sa(int s[],int n,int m)
     36 {
     37     int i,k,p,*x=t1,*y=t2;
     38     //第一轮基数排序
     39     for(i=0;i<m;i++)c[i]=0;
     40     for(i=0;i<n;i++)c[x[i]=s[i]]++;
     41     for(i=1;i<m;i++)c[i]+=c[i-1];
     42     for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
     43     for(k=1;k<=n;k<<=1){
     44         p=0;
     45         //直接利用sa数组排序第二关键字
     46         for(i=n-k;i<n;i++)y[p++]=i;
     47         for(i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
     48         //基数排序第一关键字
     49         for(i=0;i<m;i++)c[i]=0;
     50         for(i=0;i<n;i++)c[x[y[i]]]++;
     51         for(i=1;i<m;i++)c[i]+=c[i-1];
     52         for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
     53         //根据sa和x数组计算新的x数组
     54         swap(x,y);
     55         p=1;x[sa[0]]=0;
     56         for(i=1;i<n;i++)
     57             x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
     58         if(p>=n)break;   //已经排好序,直接退出
     59         m=p;     //下次基数排序的最大值
     60     }
     61 }
     62 
     63 void getHeight(int s[],int n)
     64 {
     65     int i,j,k=0;
     66     for(i=0;i<=n;i++)rank[sa[i]]=i;
     67     for(i=0;i<n;i++){
     68         if(k)k--;
     69         j=sa[rank[i]-1];
     70         while(s[i+k]==s[j+k])k++;
     71         height[rank[i]]=k;
     72     }
     73 }
     74 
     75 int binary(int l,int r)
     76 {
     77     int i,j,mid,ok1,ok2,ret;
     78     while(l<=r){
     79         mid=(l+r)>>1;
     80         ok1=ok2=0;
     81         if(sa[1]<len1)ok1=1;
     82         else if(sa[1]>len1)ok2=1;
     83         for(i=2;i<=n;i++){
     84             if(height[i]<mid)ok1=ok2=0;
     85             if(sa[i]<len1)ok1=1;
     86             else if(sa[i]>len1)ok2=1;
     87             if(ok1 && ok2)break;
     88         }
     89         if(ok1 && ok2)ret=mid,l=mid+1;
     90         else r=mid-1;
     91     }
     92     return ret;
     93 }
     94 
     95 int main()
     96 {
     97  //   freopen("in.txt","r",stdin);
     98     int i,j;
     99     while(~scanf("%s",s) && s[0]!='#')
    100     {
    101         len1=strlen(s);
    102         for(i=0;i<len1;i++)num[i]=s[i]-'a'+1;
    103         num[len1]=27;
    104         scanf("%s",s);
    105         len2=strlen(s);
    106         n=len1+len2+1;
    107         for(i++,j=0;i<n;i++,j++)num[i]=s[j]-'a'+1;
    108         num[n]=0;
    109         m=28;
    110         build_sa(num,n+1,m);
    111         getHeight(num,n);
    112 
    113         printf("%d\n",binary(0,Min(len1,len2)));
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    软件工程实践总结
  • 原文地址:https://www.cnblogs.com/zhsl/p/3040835.html
Copyright © 2011-2022 走看看