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 }
  • 相关阅读:
    Spring bean的实例化
    提交本地代码到github
    ORM框架——SQLAlchemy
    代码发布项目(三)——python操作git、代码发布流程(服务器管理、项目管理)
    代码发布项目(二)——django实现websocket(使用channels)、基于channels实现群聊功能、gojs插件、paramiko模块
    代码发布项目(一)——实现服务端主动给客户端推送消息(websocket)
    索引补充(索引种类,正确使用索引,其他注意事项,慢日志查询)
    mysql索引种类(索引种类和建立索引)
    centos6安装Docker遇到的问题(升级centos6内核)
    Django1.11下载安装xadmin
  • 原文地址:https://www.cnblogs.com/zhsl/p/3040835.html
Copyright © 2011-2022 走看看