Long Long Message POJ - 2774

Long Long Message

POJ - 2774

题意:求两个串的最长公共字串。

用特殊符号连接两个字符串,后缀数组。

枚举height,如果sa[i]和sa[i-1]分别属于不同的串,则更新最大值。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 200010;
 7 char s[maxn];
 8 int sa[maxn],t1[maxn],t2[maxn],c[maxn];
 9 int rank[maxn],height[maxn];
10
11
12 void build_sa(int n, int m){
13     int i, *x = t1, *y = t2;
14     for(i = 0; i < m; i++) c[i] = 0;
15     for(i = 0; i < n; i++) c[x[i] = s[i]]++;
16     for(i = 1; i < m; i++) c[i] += c[i-1];
17     for(i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;
18     for(int k = 1; k <= n; k <<= 1){
19         int p = 0;
20         for(i = n-k; i < n; i++) y[p++] = i;
21         for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
22         for(i = 0; i < m; i++) c[i] = 0;
23         for(i = 0; i < n; i++) c[x[y[i]]]++;
24         for(i = 1; i < m; i++) c[i] += c[i-1];
25         for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
26         swap(x,y);
27         p=1;
28         x[sa[0]]=0;
29         for(i = 1; i < n; i++)
30           x[sa[i]]= y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k] ? p-1 : p++;
31         if(p >= n) break;
32         m=p;
33     }
34 }
35 void getHeight(int n){
36     int i, j, k=0;
37     for(i = 0; i <= n; i++) rank[sa[i]] = i;
38     for(i = 0; i < n; i++) {
39         if(k) k--;
40         j = sa[rank[i]-1];
41         while(s[i+k]==s[j+k]) k++;
42         height[rank[i]] = k;
43     }
44 }
45
46 int main(){
47     while(scanf("%s",s)!=EOF){
48         int n=strlen(s);
49         int l1=n;
50         s[n]=‘#‘;
51         scanf("%s",s+n+1);
52         n=strlen(s);
53     //    cout<<s<<endl;
54         build_sa(n+1,256);
55         getHeight(n);
56         int ans=0;
57         for(int i = 1; i < n; i++){
58             if(sa[i]<l1&&sa[i-1]>l1 || sa[i]>l1&&sa[i-1]<l1){
59                 ans=max(ans,height[i]);
60             }
61         }
62         printf("%d\n",ans);
63     }
64     return 0;
65 }

时间: 2024-10-28 23:21:06

Long Long Message POJ - 2774的相关文章

POJ 2774 Long Long Message (最长公共子串)

Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 27062   Accepted: 11010 Case Time Limit: 1000MS Description The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days

poj 2774 Long Long Message(后缀数组入门题)

1 /****************************************************************** 2 题目: Long Long Message(poj 2774) 3 链接: http://poj.org/problem?id=2774 4 题意: 给两个字符串,找最长的公共子串 5 算法: 后缀数组 6 算法思想: 后缀数组就是套模板求先应得数组,这题用到了两个数组,分 7 别是sa[],height[];sa[i]表示所有后缀按字典数排序后以s[i

[POJ 2774] Long Long Message 【后缀数组】

题目链接:POJ - 2774 题目分析 题目要求求出两个字符串的最长公共子串,使用后缀数组求解会十分容易. 将两个字符串用特殊字符隔开再连接到一起,求出后缀数组. 可以看出,最长公共子串就是两个字符串分别的一个后缀的 LCP ,并且这两个后缀在 SA 中一定是相邻的. 那么他们的 LCP 就是 Height[i] ,当然,Height[i] 的最大值不一定就是 LCS ,因为可能 SA[i] 和 SA[i-1] 是在同一个字符串中. 那么判断一下,如果 SA[i] 与 SA[i - 1] 分别

POJ 2774 后缀数组:求最长公共子串

思路:其实很简单,就是两个字符串连接起来,中间用个特殊字符隔开,然后用后缀数组求最长公共前缀,然后不同在两个串中,并且最长的就是最长公共子串了. 注意的是:用第一个字符串来判断是不是在同一个字符中,刚开始用了第二个字符的长度来判断WA了2发才发现. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<

poj 2774 最长公共子串--字符串hash或者后缀数组或者后缀自动机

http://poj.org/problem?id=2774 想用后缀数组的看这里:http://blog.csdn.net/u011026968/article/details/22801015 本文主要讲下怎么hash去找 开始的时候写的是O(n^2 logn)算法 果断超时...虽然也用了二分的,, 代码如下: //hash+二分 #include <cstdio> #include <cstring> #include <algorithm> #include

poj 2774 Long Long Message 后缀数组

点击打开链接题目链接 Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 23327   Accepted: 9566 Case Time Limit: 1000MS Description The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him

POJ 2774 Long Long Message &amp;&amp; URAL 1517. Freedom of Choice(求最长重复子序列)

两个题目意思差不多,都是让求最长公共子串,只不过poj那个让输出长度,而URAL那个让输出一个任意的最长的子串. 解体思路: Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 22313   Accepted: 9145 Case Time Limit: 1000MS Description The little cat is majoring in physics in the cap

POJ 2774 Long Long Message(后缀数组)

[题目链接] http://poj.org/problem?id=2774 [题目大意] 求最长公共子串 [题解] 将两个串中间嵌一个字符相连,求一遍后缀数组 如果排名相邻的两个后缀的开端是分属于两个串的, 那么他们的最长公共前缀就可以用来更新答案 [代码] #include <cstdio> #include <cstring> using namespace std; const int N=4000010; int n,rank[N],sa[N],h[N],tmp[N],cn

poj 2774:Long Long Message

Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 25018   Accepted: 10237 Case Time Limit: 1000MS Description The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days: his mother is ge