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 these days: his mother is getting ill. Being worried about spending so much on railway tickets (Byterland is such a big country, and he has to spend 16 shours
on train to his hometown), he decided only to send SMS with his mother.

The little cat lives in an unrich family, so he frequently comes to the mobile service center, to check how much money he has spent on SMS. Yesterday, the computer of service center was broken, and printed two very long messages. The brilliant little cat soon
found out:

1. All characters in messages are lowercase Latin letters, without punctuations and spaces.

2. All SMS has been appended to each other – (i+1)-th SMS comes directly after the i-th one – that is why those two messages are quite long.

3. His own SMS has been appended together, but possibly a great many redundancy characters appear leftwards and rightwards due to the broken computer.

E.g: if his SMS is “motheriloveyou”, either long message printed by that machine, would possibly be one of “hahamotheriloveyou”, “motheriloveyoureally”, “motheriloveyouornot”, “bbbmotheriloveyouaaa”, etc.

4. For these broken issues, the little cat has printed his original text twice (so there appears two very long messages). Even though the original text remains the same in two printed messages, the redundancy characters on both sides would be possibly different.

You are given those two very long messages, and you have to output the length of the longest possible original text written by the little cat.

Background:

The SMS in Byterland mobile service are charging in dollars-per-byte. That is why the little cat is worrying about how long could the longest original text be.

Why ask you to write a program? There are four resions:

1. The little cat is so busy these days with physics lessons;

2. The little cat wants to keep what he said to his mother seceret;

3. POJ is such a great Online Judge;

4. The little cat wants to earn some money from POJ, and try to persuade his mother to see the doctor :(

Input

Two strings with lowercase letters on two of the input lines individually. Number of characters in each one will never exceed 100000.

Output

A single line with a single integer number – what is the maximum length of the original text written by the little cat.

Sample Input

yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
yeaphowmuchiloveyoumydearmother

Sample Output

27

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

用了罗穗骞的模板 - -

#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 222222
using namespace std;
int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN];
int sa[MAXN],height[MAXN],ranks[MAXN];
char str[MAXN*2];
int r[MAXN*2];
int cmp(int *q,int a,int b,int l){
    return q[a]==q[b]&&q[a+l]==q[b+l];
}
void da(int n,int m){
    int i,j,p,*x=wa,*y=wb,*t;
    for(i=0;i<m;i++)    ws[i]=0;
    for(i=0;i<n;i++)    ws[x[i]=r[i]]++;
    for(i=1;i<m;i++)    ws[i]+=ws[i-1];
    for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
    for(j=1,p=1;p<n;j*=2,m=p){
        for(p=0,i=n-j;i<n;i++)  y[p++]=i;
        for(i=0;i<n;i++)    if(sa[i]>=j) y[p++]=sa[i]-j;
        for(i=0;i<n;i++)    wv[i]=x[y[i]];
        for(i=0;i<m;i++)    ws[i]=0;
        for(i=0;i<n;i++)    ws[wv[i]]++;
        for(i=1;i<m;i++)    ws[i]+=ws[i-1];;
        for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
        for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
            x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    }
}
void getheight(int n){
    int i,j,k=0;
    for(i=1;i<=n;i++)   ranks[sa[i]]=i;
    for(i=0;i<n;height[ranks[i++]]=k)
    for(k?k--:0,j=sa[ranks[i]-1];r[i+k]==r[j+k];k++);
}
int main(){
    scanf("%s",str);
    int l1=strlen(str);
    str[l1]=1;
    scanf("%s",str+l1+1);
    int l=strlen(str);
    for(int i=0;i<l;i++)
        r[i]=str[i];
    r[l]=0;
    da(l+1,128);
    getheight(l);
    int ans=0;
    for(int i=2;i<=l;i++){
        if(height[i]>ans)
            if((l1<sa[i-1]&&sa[i]<l1)||(l1>sa[i-1]&&sa[i]>l1))
                ans=height[i];

    }
    printf("%d\n",ans);
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 16:19:56

poj 2774 Long Long Message 后缀数组的相关文章

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 后缀数组基础题

Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 24756   Accepted: 10130 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

poj 2774 Long Long Message 后缀数组LCP理解

题目链接 题意:给两个长度不超过1e5的字符串,问两个字符串的连续公共子串最大长度为多少? 思路:两个字符串连接之后直接后缀数组+LCP,在height中找出max同时满足一左一右即可: #include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<map> #include<queue&

POJ 2774 Long Long Message ——后缀数组

[题目分析] 用height数组RMQ的性质去求最长的公共子串. 要求sa[i]和sa[i-1]必须在两个串中,然后取height的MAX. 利用中间的字符来连接两个字符串的思想很巧妙,记得最后还需要空一个位置避免冲突. [代码] #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <map> #include <set>

PKU 2774 Long Long Message (后缀数组练习模板题)

题意:给你两个字符串,求最长公共字串的长度. by:罗穗骞模板 #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define M 303 #define inf 0x3fffffff #define maxn 500000 #define ws ww #define rank RANK #define F

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 1743 Musical Theme (后缀数组)

题目大意: 刚才上88个键弹出来的音符. 如果出现重复的,或者是高一个音阶的重复的都算. 思路分析: 具体可以参考训练指南222. height数组表示按照排序后的sa最近的两个后缀的最长前缀. 将height 分块.然后二分答案,二分答案之后去判断是否满足. 要考虑到不重合,还有大于5. 所以二分的时候要从5开始,然后判断的时候要加一个 up - down >len #include <cstdio> #include <iostream> #include <alg

HUID 5558 Alice&#39;s Classified Message 后缀数组+单调栈+二分

http://acm.hdu.edu.cn/showproblem.php?pid=5558 对于每个后缀suffix(i),想要在前面i - 1个suffix中找到一个pos,使得LCP最大.这样做O(n^2) 考虑到对于每一个suffix(i),最长的LCP肯定在和他排名相近的地方取得. 按排名大小顺序枚举位置,按位置维护一个递增的单调栈,对于每一个进栈的元素,要算一算栈内元素和他的LCP最大是多少. 如果不需要输出最小的下标,最大的直接是LCP(suffix(st[top]),  suff

POJ 3729 Facer’s string (后缀数组)

题目大意: 串1中有多少个后缀和 串2中的某个后缀 的lcp 为 k 思路分析: 先找出 长度至少为k的对数有多少. 再找出 至少为k+1的有多少 然后相减. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <map> #include <string> #define maxn 110005 using na