Long Long Message
Time Limit: 4000MS   Memory Limit: 131072K
Total Submissions: 35607   Accepted: 14275
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

这个题目百来就是一道后缀数组的入门题,然后发现二分哈希也能做,于是就都打打。。。

后缀数组:432ms
 #include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring> using namespace std; const int N = ; int l1, m, n, l2;
int c[N], x[N], y[N], sa[N], ht[N], rk[N];
char s1[N], s2[N], s[N]; inline void Get_Sa()
{
for (int i = ; i <= n; ++i) ++c[x[i] = s[i]];
for (int i = ; i <= m; ++i) c[i] += c[i - ];
for (int i = n; i >= ; --i) sa[c[x[i]]--] = i;
for (int k = ; k <= n; k <<= )
{
int num = ;
for (int i = n - k + ; i <= n; ++i) y[++num] = i;
for (int i = ; i <= n; ++i) if (sa[i] > k) y[++num] = sa[i] - k;
for (int i = ; i <= m; ++i) c[i] = ;
for (int i = ; i <= n; ++i) ++c[x[i]];
for (int i = ; i <= m; ++i) c[i] += c[i - ];
for (int i = n; i >= ; --i) sa[c[x[y[i]]]--] = y[i], y[i] = ;
for (int i = ; i <= n; ++i) y[i] = x[i], x[i] = ;
swap(x, y), x[sa[]] = , num = ;
for (int i = ; i <= n; ++i)
x[sa[i]] = (y[sa[i]] == y[sa[i - ]] && y[sa[i] + k] == y[sa[i - ] + k]) ? num : ++num;
if (num == n) break; m = num;
}
for (int i = ; i <= n; ++i) rk[sa[i]] = i;
} inline void Get_Ht()
{
int k = ;
for (int i = ; i <= n; ++i)
{
if (rk[i] == ) continue;
if (k) --k;
int j = sa[rk[i] - ];
while (j + k <= n && i + k <= n
&& s[i + k] == s[j + k]) ++k;
ht[rk[i]] = k;
}
} int main()
{
while (~scanf("%s%s", s + , s2 + ))
{
int ans = -;
l1 = strlen(s + );
l2 = strlen(s2 + );
s[l1 + ] = '$';
m = ;
for (int i = ; i <= l2; ++i)
s[l1 + + i] = s2[i];
n = strlen(s + );
Get_Sa(), Get_Ht();
for (int i = ; i <= n; ++i)
if (sa[i - ] >= && sa[i - ] <= l1 && sa[i] >= l1 + )
ans = max(ans, ht[i]);
else if (sa[i] >= && sa[i] <= l1 && sa[i - ] >= l1 + )
ans = max(ans, ht[i]);
// for (int i = 1; i <= n; ++i)
// printf("%s %d\n", s + sa[i], ht[i]);
printf("%d\n", ans);
}
return ;
}

二分+哈希:1463ms

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio> using namespace std;
typedef unsigned long long ull; const ull N = ;
const ull base = ; int l1, l2, L, R;
ull bit[N], f[N], h1[N], h2[N];
char s2[N], s1[N]; inline bool good(int l)
{
int tot = ;
for (int i = ; i <= l1 - l + ; ++i)
f[++tot] = h1[i + l - ] - h1[i - ] * bit[l];
sort(f + , f + tot + );
for (int i = ; i <= l2 - l + ; ++i)
if (binary_search(f + , f + tot + , h2[i + l - ] - h2[i - ] * bit[l]))
return true;
return false;
} int main()
{
for (int i = ; i <= N - ; ++i) bit[i] = (i == ? : bit[i - ]) * base;
while (~scanf("%s%s", s1 + , s2 + ))
{
l1 = strlen(s1 + ), l2 = strlen(s2 + );
for (int i = ; i <= l1; ++i) h1[i] = h1[i - ] * base + (s1[i] - );
for (int i = ; i <= l2; ++i) h2[i] = h2[i - ] * base + (s2[i] - );
L = , R = max(l1, l2) + ;
while (L <= R)
{
int mid = (L + R) >> ;
if (good(mid)) L = mid + ;
else R = mid - ;
}
printf("%d\n", R);
}
return ;
}

(虽然慢一点,但哈希真的好写!!!!)

POJ 2774 后缀数组 || 二分+哈希的更多相关文章

  1. POJ 2774 后缀数组

    题目链接:http://poj.org/problem?id=2774 题意:给定两个只含小写字母的字符串,求字符串的最长公共子串长度. 思路:根据<<后缀数组——处理字符串的有力工具&g ...

  2. 2016vijos 1-1 兔子的字符串(后缀数组 + 二分 + 哈希)

    题意: 给出一个字符串,至多将其划分为n部分,每一部分取出字典序最大的子串ci,最小化 最大的ci 先看一个简化版的问题: 给一个串s,再给一个s的子串t,问能否通过将串划分为k个部分,使t成为划分后 ...

  3. POJ 2774 后缀数组:查找最长公共子

    思考:其实很easy.就在两个串在一起.通过一个特殊字符,中间分隔,然后找到后缀数组的最长的公共前缀.然后在两个不同的串,最长是最长的公共子串. 注意的是:用第一个字符串来推断是不是在同一个字符中,刚 ...

  4. POJ 3261 (后缀数组 二分) Milk Patterns

    这道题和UVa 12206一样,求至少重复出现k次的最长字串. 首先还是二分最长字串的长度len,然后以len为边界对height数组分段,如果有一段包含超过k个后缀则符合要求. #include & ...

  5. POJ 1743 (后缀数组 二分) Musical Theme

    看来对height数组进行分段确实是个比较常用的技巧. 题意: 一个主题是可以变调的,也就是如果这个主题所有数字加上或者减少相同的数值,可以看做是相同的主题. 一个主题在原串中至少要出现两次,而且一定 ...

  6. poj 2774 后缀数组 两个字符串的最长公共子串

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 31904   Accepted: 12 ...

  7. POJ 3261 后缀数组+二分

    思路: 论文题- 二分+对后缀分组 这块一开始不用基数排序 会更快的(其实区别不大) //By SiriusRen #include <cstdio> #include <cstri ...

  8. Long Long Message POJ - 2774 后缀数组

    The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him ...

  9. POJ 2774 (后缀数组 最长公共字串) Long Long Message

    用一个特殊字符将两个字符串连接起来,然后找最大的height,而且要求这两个相邻的后缀的第一个字符不能在同一个字符串中. #include <cstdio> #include <cs ...

随机推荐

  1. Python网络爬虫(一)

    Urllib发送请求 基本用法 基本的用法就是调用request库, class urllib.request.Request(url, data=None, headers={}, origin_r ...

  2. POJ 2068 NIm (dp博弈,每个人都有特定的取最大值)

    题目大意: 有2n个人,从0开始编号,按编号奇偶分为两队,循环轮流取一堆有m个石子的石堆,偶数队先手,每个人至少取1个,至多取w[i]个,取走最后一个石子的队伍输.问偶数队是否能赢. 分析: 题目数据 ...

  3. HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)

    题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...

  4. mysql /etc/my.cnf

    [client] port=3306 socket = /tmp/mysql.sock default-character-set=utf8 [mysqld] # 1 general config p ...

  5. C#基础之类型和成员基础以及常量、字段、属性

    首先吐糟一下今天杭州的天气,真是太热了!虽然没有妹子跟我约会,但宅在方寸大的窝里,也是烦躁不已! 接上一篇<C#基础之基本类型> 类型和成员基础 在C#中,一个类型内部可以定义多种成员:常 ...

  6. C# ThreadLocal

    ThreadLocal的主要作用是让各个线程维持自己的变量. .NET 4.0在线程方面加入了很多东西,其中就包括ThreadLocal<T>类型,他的出现更大的简化了TLS的操作.Thr ...

  7. JNA-调用win32 Dll文件

    1. 描述备注 参考地址1 JNA示例代码 1.1 JNA工作原理 JNA是建立在JNI技术基础之上的一个Java类库,它使您可以方便地使用java直接访问动态链接库中的函数. 原来使用JNI,你必须 ...

  8. python接口自动化(四十一)- 发xml格式参数的post请求(超详解)

    简介 最近在工作中,遇到一种奇葩的接口,它的参数数据是通过xml,进行传递的,不要大惊小怪的,林子大了什么鸟都有,每个人的思路想法不一样,开发的接口也是各式各样的,如果想要统一的话,必须是提前团队已经 ...

  9. linux安装gcc和gcc-c++

    有些VPS中使用的是精简版Linux,上篇linux下自动备份blog到dropbox中的gcc和gcc-c++编译器没安装,无法编译出链接的"hostid",下面是Linux安装 ...

  10. 动态页面技术----EL技术、JSTL技术,javaEE的开发模式

    1 EL技术 1.1 EL 表达式 EL(Express Lanuage)表达式可以嵌入在jsp页面内部,减少jsp脚本的编写, EL出现的目的是要替代jsp页面中脚本的编写,就是简化java代码. ...