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

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

    拼接两个字符串中间用特殊字符隔开,max(height[i])(2<=i<=len,suffix(sa[i])与suffix(sa[i-1])分别属于两个字符串的后缀)就是答案!

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 using namespace std;
     6 #define MAXN 222222 
     7 int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN];
     8 int cmp(int *r,int a,int b,int l){
     9     return r[a]==r[b] && r[a+l]==r[b+l];
    10 }
    11 int sa[MAXN],rank[MAXN],height[MAXN];
    12 void SA(int *r,int n,int m){
    13     int *x=wa,*y=wb;
    14 
    15     for(int i=0; i<m; ++i) ws[i]=0;
    16     for(int i=0; i<n; ++i) ++ws[x[i]=r[i]];
    17     for(int i=1; i<m; ++i) ws[i]+=ws[i-1];
    18     for(int i=n-1; i>=0; --i) sa[--ws[x[i]]]=i;
    19 
    20     int p=1;
    21     for(int j=1; p<n; j<<=1,m=p){
    22         p=0;
    23         for(int i=n-j; i<n; ++i) y[p++]=i;
    24         for(int i=0; i<n; ++i) if(sa[i]>=j) y[p++]=sa[i]-j;
    25         for(int i=0; i<n; ++i) wv[i]=x[y[i]];
    26         for(int i=0; i<m; ++i) ws[i]=0;
    27         for(int i=0; i<n; ++i) ++ws[wv[i]];
    28         for(int i=1; i<m; ++i) ws[i]+=ws[i-1];
    29         for(int i=n-1; i>=0; --i) sa[--ws[wv[i]]]=y[i];
    30         swap(x,y); x[sa[0]]=0; p=1;
    31         for(int i=1; i<n; ++i) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    32     }
    33 
    34     for(int i=1; i<n; ++i) rank[sa[i]]=i;
    35     int k=0;
    36     for(int i=0; i<n-1; height[rank[i++]]=k){
    37         if(k) --k;
    38         for(int j=sa[rank[i]-1]; r[i+k]==r[j+k]; ++k);
    39     }
    40 }
    41 
    42 int r[MAXN];
    43 char str[MAXN];
    44 int main(){
    45     int n=0,m;
    46     scanf("%s",str);
    47     for(int i=0; str[i]; ++i) r[n++]=str[i]-'a'+1;
    48     m=n;
    49     r[n++]=27;
    50     scanf("%s",str);
    51     for(int i=0; str[i]; ++i) r[n++]=str[i]-'a'+1;
    52     r[n]=0;
    53     SA(r,n+1,28);
    54     int res=0;
    55     for(int i=2; i<=n; ++i){
    56         if(sa[i]>m&&sa[i-1]<m || sa[i]<m&&sa[i-1]>m) res=max(res,height[i]);
    57     }
    58     printf("%d",res);
    59     return 0;
    60 }
  • 相关阅读:
    flask-script插件
    狗书(flask基础)
    2018.1.18纪事
    py3.6 + xadmin的自学网站搭建
    使用selenium抓取淘宝的商品信息
    pyquery操作
    requests模块
    python3里的Urllib库
    随便写点
    How many ways?? HDU
  • 原文地址:https://www.cnblogs.com/WABoss/p/5208120.html
Copyright © 2011-2022 走看看