后缀数组 POJ 2217 Secretary
题意:求两个字符串的最长公共子串
分析:做法是构造新的串是两个串连接而成,中间用没有出现的字符隔开(因为这样才能保证S的后缀的公共前缀不会跨出一个原有串的范围),即newS = S + '$' + T。对其求sa数组和height数组,取最小值的height[i],且两个后缀串属于不同的字符串。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string> typedef long long ll;
const int N = 1e4 + 5;
std::string t, str;
int sa[N<<1], rank[N<<1];
int height[N<<1];
int tmp[N<<1]; int n, k;
bool cmp_sa(int i, int j) {
if (rank[i] != rank[j]) {
return rank[i] < rank[j];
} else {
int ri = i + k <= n ? rank[i+k] : -1;
int rj = j + k <= n ? rank[j+k] : -1;
return ri < rj;
}
} void get_sa(std::string S, int *sa) {
n = S.length ();
for (int i=0; i<=n; ++i) {
sa[i] = i;
rank[i] = i < n ? (int) S[i] : -1;
}
for (k=1; k<=n; k<<=1) {
std::sort (sa, sa+n+1, cmp_sa);
tmp[sa[0]] = 0;
for (int i=1; i<=n; ++i) {
tmp[sa[i]] = tmp[sa[i-1]] + (cmp_sa (sa[i-1], sa[i]) ? 1 : 0);
}
for (int i=0; i<=n; ++i) {
rank[i] = tmp[i];
}
}
} void get_height(std::string S, int *sa, int *height) {
int n = S.length ();
for (int i=0; i<n; ++i) {
rank[sa[i]] = i;
}
int h = 0;
height[0] = 0;
for (int i=0; i<n; ++i) {
int j = sa[rank[i]-1];
if (h > 0) {
h--;
}
for (; j+h<n && i+h<n; h++) {
if (S[j+h] != S[i+h]) {
break;
}
}
height[rank[i]-1] = h;
}
} int run(int len1, std::string S) {
get_sa (S, sa);
get_height (S, sa, height);
int ret = 0;
for (int i=0; i<S.length (); ++i) {
if ((sa[i]<len1) != (sa[i+1]<len1)) {
ret = std::max (ret, height[i]);
}
}
return ret;
} int main() {
int T; scanf ("%d", &T);
getchar ();
while (T--) {
getline (std::cin, t);
str = t;
int len1 = t.length ();
getline (std::cin, t);
str += '$' + t;
int ans = run (len1, str);
printf ("Nejdelsi spolecny retezec ma delku %d.\n", ans);
}
return 0;
}
后缀数组 POJ 2217 Secretary的更多相关文章
- POJ 2217 Secretary (后缀数组)
标题效果: 计算两个公共串串最长的字符串的长度. IDEAS: 这两个组合的字符串. 然后直接确定运行后缀数组height 然后,你可以直接扫描一次height .加个是不是在一个串中的推断就能够了. ...
- POJ 2217 Secretary
Secretary Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: ...
- 后缀数组 POJ 1743 Musical Theme
题目链接 题意:给定n个数字,求超过5个数字的,最长的,变化相同的,不相交的重复子串 分析:男人8题中的一题!数列相邻两项做差,形成新数列,即求数列中的最长重复子串(不可相交). 后缀数组+二分答案. ...
- 后缀数组 POJ 3581 Sequence
题目链接 题意:把n个数字(A1比其他数字都大)的序列分成三段,每段分别反转,问字典序最小的序列. 分析:因为A1比其他数字都大,所以反转后第一段结尾是很大的数,相当是天然的分割线,第一段可以单独考虑 ...
- 后缀数组 POJ 3261 Milk Patterns
题目链接 题意:可重叠的 k 次最长重复子串.给定一个字符串,求至少出现 k 次的最长重复子串,这 k 个子串可以重叠. 分析:与POJ 1743做法类似,先二分答案,height数组分段后统计 LC ...
- 后缀数组 poj 3415
首先,height[i]-k+1 很好理解把,他是说明目前这对后缀中不小于k的公共子串个数. 题解说用单调栈维护,为什么要用单调栈维护呢?因为时间复杂的可以大大降低. 怎么个降低方法呢? 在之前学习 ...
- 后缀数组 POJ 3693 Maximum repetition substring
题目链接 题意:给定一个字符串,求重复次数最多的连续重复子串. 分析:(论文上的分析)先穷举长度 L,然后求长度为 L 的子串最多能连续出现几次.首先连续出现 1 次是肯定可以的,所以这里只考虑至少 ...
- 后缀数组 POJ 3974 Palindrome && URAL 1297 Palindrome
题目链接 题意:求给定的字符串的最长回文子串 分析:做法是构造一个新的字符串是原字符串+反转后的原字符串(这样方便求两边回文的后缀的最长前缀),即newS = S + '$' + revS,枚举回文串 ...
- 【后缀数组】bzoj2217 Secretary
考虑简化问题:计算一个字符串中至少出现两次的最长子串.答案一定会在sa中相邻两个后缀的lcp中.因为后缀的位置在sa中相距越远,其lcp的长度就越短,这是由于字典序的性质决定的. 于是,在s1和s2中 ...
随机推荐
- PHP安全编程:过滤用户输入
如果你能正确可靠地识别和过滤输入,你的工作就基本完成了.最后一步是使用一个命名约定或其它可以帮助你正确和可靠地区分已过滤和被污染数据的方 法.我推荐一个比较简单的命名约定,因为它可以同时用在面向过程和 ...
- Spring控制反转与依赖注入(IOC、DI)
IOC: 反转控制 Inverse Of Control DI:依赖注入 Dependency Injection 目的:完成程序的解耦合 解释:在应用系统的开发过程中,有spring负责对象的创 ...
- [Android Pro] StarUML 版本破解
参考:http://bbs.chinapyg.com/thread-79022-1-1.html 官网下载地址 : http://staruml.en.softonic.com 各平台版本均适用,本文 ...
- ios框架
iPhone OS(现在叫iOS)是iPhone, iPod touch 和 iPad 设备的操作系统. 1,Core OS: 是用FreeBSD和Mach所改写的Darwin, 是开源 ...
- Hadoop家族 路线图(转)
主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pig, HBase, Sqoop, Mahout, Zookeeper, Avro, Ambari, Chukwa,新增加的项 ...
- hdu 1279 验证角谷猜想
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1279 #include<stdlib.h> #include<time.h> ...
- DLog的使用
DLog本质上就是个宏替换.DLog具体代码如下: #ifdef DEBUG #define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt) ...
- OID View
http://oid-info.com/get/1.3.6.1.2.1.17.1.4.1.2
- Linux Shell 高级编程技巧3----运行级别脚本介绍
3.运行级别脚本介绍 3.1.运行级别 运行级别介绍: 0 关机 1 单用户模式 2 多用户模式 ...
- MVC基础知识
1.View中获取Control和View: //获取控制器名称: ViewContext.RouteData.Values["controller"].ToString(); / ...