【poj2774】Long Long Message

用个分隔符将两个字符串连接起来,再用后缀数组求出height数组的值,找出一个height值最大并且i与i-1的sa值分别在两串字符中就好

 

 1 #include<algorithm>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 using namespace std;
 7 
 8 #define N 200010
 9 
10 int wa[N],wb[N],wv[N],ws[N];
11 int height[N],rank[N],sa[N];
12 
13 int num[N];
14 char str[N];
15 
16 int cmp(int *r,int a,int b,int l)
17 {
18     return r[a]==r[b] && r[a+l]==r[b+l];
19 }
20 
21 void da(int *r,int n,int m)
22 {
23     int i,j,p,*x=wa,*y=wb,*t;
24     for (i=0;i<m;i++) ws[i]=0;
25     for (i=0;i<n;i++) ws[x[i]=r[i]]++;
26     for (i=1;i<m;i++) ws[i]+=ws[i-1];
27     for (i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
28     for (j=1,p=1;p<n;j*=2,m=p)
29     {
30         for (p=0,i=n-j;i<n;i++) y[p++]=i;
31         for (i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j;
32         for (i=0;i<n;i++) wv[i]=x[y[i]];
33         for (i=0;i<m;i++) ws[i]=0;
34         for (i=0;i<n;i++) ws[wv[i]]++;
35         for (i=1;i<m;i++) ws[i]+=ws[i-1];
36         for (i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
37         for (t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
38             x[sa[i]]=cmp(y,sa[i-1],sa[i],j) ? p-1 : p++;
39     }
40     return ;
41 }
42 
43 void calheight(int *r,int n)
44 {
45     int i,j,k=0;
46     for (i=1;i<=n;i++) rank[sa[i]]=i;
47     for (i=0;i<n;height[rank[i++]]=k)
48         for (k ? k-- : 0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
49     return ;
50 }
51 
52 int main()
53 {
54     int i,k,l1,l2;
55     scanf("%s",str);
56     l1=strlen(str);
57     for (k=i=0;i<l1;i++)
58         num[k++]=str[i]-'a'+2;
59     num[k++]=1;
60     scanf("%s",str);
61     l2=strlen(str);
62     for (i=0;i<l2;i++)
63         num[k++]=str[i]-'a'+2;
64     int n=l1+l2;
65     da(num,n+1,30);
66     calheight(num,n);
67     int ans=0;
68     for (i=2;i<k;i++)
69         if ((sa[i]<l1 && sa[i-1]>l1) || (sa[i-1]<l1 && sa[i]>l1))
70             ans=max(ans,height[i]);
71     printf("%d\n",ans);
72     return 0;
73 }

 

posted @ 2016-04-08 16:15  Yangjiyuan  阅读(184)  评论(0编辑  收藏  举报