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. Windows 新增 Sublime Text3 右键快捷方式

    Win10 创建 Sublime Text 3 右键快捷方式 Windows + R 输入 regedit 打开注册表编辑器: 依次找到 计算机\HKEY_CLASSES_ROOT\*\shell: ...

  2. [Leetcode]008.String to Integer (atoi)

    public class Solution { public int myAtoi(String str) { int index = 0, sign = 1, total = 0; //1. 边界条 ...

  3. Luogu P4161 [SCOI2009]游戏 数论+DP

    ywy神犇太巨辣!!一下就明白了!! 题意:求$lcm(a_1,a_2,...,a_k)$的种类,其中$\Sigma\space a_i <=n$,$a_i$相当于环长 此处的$DP$,相当于是 ...

  4. P1977 出租车拼车(DP)

    题目背景 话说小 x 有一次去参加比赛,虽然学校离比赛地点不太远,但小 x 还是想坐 出租车去.大学城的出租车总是比较另类,有“拼车”一说,也就是说,你一个人 坐车去,还是一堆人一起,总共需要支付的钱 ...

  5. JS——数组、==和===的区别

    创建数组的方式: 1) <script type='text/javascript'> var aRr = new Array(1,2,3,4,'abc',3) </script&g ...

  6. sqoop导出hive数据到mysql错误: Caused by: java.lang.RuntimeException: Can't parse input data

    Sqoop Export数据到本地数据库时出现错误,命令如下: sqoop export \ --connect 'jdbc:mysql://202.193.60.117/dataweb?useUni ...

  7. win7,docker安装后,创建虚拟机分配不了ip错误 err: exit status 255

    问题 win7装docker真麻烦,不如家里的win10爽.另外明明这是个很简单的操作,但是国内的解决方法有点落后,所以我写了个傻瓜式的. 有兴趣的可以直接看issue https://github. ...

  8. Java规则引擎drools:drt动态生成规则并附上具体项目逻辑

    一 整合 由于本人的码云太多太乱了,于是决定一个一个的整合到一个springboot项目里面. 附上自己的项目地址https://github.com/247292980/spring-boot 以整 ...

  9. web.config文件executionTimeout的单位

      executionTimeout:表示允许执行请求的最大时间限制,单位为秒

  10. Eucalyptus-利用镜像启动一个Windows Server 2008r2实例

    1.前言 使用kvm制作Eucalyptus镜像(Windows Server 2008r2为例)——http://www.cnblogs.com/gis-luq/p/3990792.html 上一篇 ...