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. hive_hiveserver2 hive-site.xml config and start

    hive-site.xml # vi hive-site.xml <configuration> <property> <name>javax.jdo.option ...

  2. springMVC form表单提交多个对象集合--使用ajax提交--前台json格式数据封装方法

    (function ($) { $.fn.serializeJson = function () { var jsonData1 = {}; var serializeArray = this.ser ...

  3. redis常用

    redis的key和string类型value限制均为512MB

  4. Testlink安装配置时常见问题解决

    1.windows下安装testlink,进入安装页面后,在检查一些相关配置环境时报错,如下: Checking if /var/testlink/logs/ directory exists [S] ...

  5. Is It A Tree?(hdu1325)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1325 Is It A Tree? Time Limit: 2000/1000 MS (Java/Oth ...

  6. CentOS 7 iptables 开放8080端口

    # 安装iptables-services [root@localhost bin]# yum install iptables-services [root@localhost bin]# /bin ...

  7. (转)/etc/sysctl.conf 调优 & 优化Linux内核参数

    /etc/sysctl.conf 调优 & 优化Linux内核参数 from: http://apps.hi.baidu.com/share/detail/15652067 http://ke ...

  8. Storm概念学习系列之storm核心组件

    不多说,直接上干货! Storm核心组件 了解 Storm 的核心组件对于理解 Storm 原理非常重要,下面介绍 Storm 的整体,然后介绍 Storm 的核心. Storm 集群由一个主节点和多 ...

  9. Storm概念学习系列之storm出现的背景

      不多说,直接上干货! storm出现的背景 互联网从诞生的第一时间起,对世界的最大改变就是让信息能够实时交互,从而大大加速了各个环节的效率.正因为大家有对信息实时响应.实时交互的需求,所以软件行业 ...

  10. SpringBoot | 第十八章:web应用开发之WebJars使用

    前言 前面一章节我们主要讲解了关于文件上传的两种方式.本章节继续web开发的相关知识点.通常对于web开发而言,像js.css.images等静态资源版本管理是比较混乱的,比如Jquery.Boots ...