题面

HiHocoder1415

Poj2774

Sol

都是求最长公共子串,\(hihocoder\)上讲的很清楚

把两个串拼在一起,中间用一个特殊字符隔开

那么答案就是排序后相邻两个不同串的后缀的\(height\)

为什么呢?

如果答案为不相邻的两个后缀的前缀,计算它们最长前缀时必定要跨越过这些中间\(height\)值,也就是选相邻的两个一定要比不选相邻的两个更优

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(200010); IL ll Read(){
RG char c = getchar(); RG ll x = 0, z = 1;
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
} int n, a[_], sa[_], rk[_], y[_], h[_], height[_], t[_], ans;
char A[_], B[_]; IL bool Cmp(RG int i, RG int j, RG int k){ return y[i] == y[j] && y[i + k] == y[j + k]; } IL void Sort(){
RG int m = 27;
for(RG int i = 1; i <= n; ++i) ++t[rk[i] = a[i]];
for(RG int i = 1; i <= m; ++i) t[i] += t[i - 1];
for(RG int i = n; i; --i) sa[t[rk[i]]--] = i;
for(RG int k = 1; k <= n; k <<= 1){
RG int l = 0;
for(RG int i = n - k + 1; i <= n; ++i) y[++l] = i;
for(RG int i = 1; i <= n; ++i) if(sa[i] > k) y[++l] = sa[i] - k;
for(RG int i = 0; i <= m; ++i) t[i] = 0;
for(RG int i = 1; i <= n; ++i) ++t[rk[y[i]]];
for(RG int i = 1; i <= m; ++i) t[i] += t[i - 1];
for(RG int i = n; i; --i) sa[t[rk[y[i]]]--] = y[i];
swap(rk, y); rk[sa[1]] = l = 1;
for(RG int i = 2; i <= n; ++i) rk[sa[i]] = Cmp(sa[i - 1], sa[i], k) ? l : ++l;
if(l >= n) break; m = l;
}
for(RG int i = 1; i <= n; ++i){
h[i] = max(0, h[i - 1] - 1);
if(rk[i] == 1) continue;
while(a[i + h[i]] == a[sa[rk[i] - 1] + h[i]]) ++h[i];
}
for(RG int i = 1; i <= n; ++i) height[i] = h[sa[i]];
} IL bool Diff(RG int a, RG int b, RG int c){ return (a <= c && b > c) || (a > c && b <= c); } int main(RG int argc, RG char* argv[]){
scanf(" %s %s", A, B); RG int l1 = strlen(A), l2 = strlen(B);
for(RG int i = 0; i < l1; ++i) a[++n] = A[i] - 'a' + 1; a[++n] = 27;
for(RG int i = 0; i < l2; ++i) a[++n] = B[i] - 'a' + 1;
Sort();
for(RG int i = 2; i <= n; ++i)
if(Diff(sa[i - 1], sa[i], l1)) ans = max(ans, height[i]);
printf("%d\n", ans);
return 0;
}

HiHocoder1415 : 后缀数组三·重复旋律3 & Poj2774:Long Long Message的更多相关文章

  1. HihoCoder1415后缀数组三·重复旋律3

    重复旋律3 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多 ...

  2. hihocoder1415 后缀数组三·重复旋律3

    传送门:http://hihocoder.com/problemset/problem/1415 [题解] 考虑求出两串合在一起(中间加分隔符)后缀数组,就是要求任意在两个串中的$i, j$,$\mi ...

  3. hihocoder-1415 后缀数组三·重复旋律3 两个字符串的最长公共子串

    把s1,s2拼接,求Height.相邻的Height判断左右串起点是否在两个串中,另外对Height和s1.length()-SA[i-1]取min. #include <iostream> ...

  4. hiho一下122周 后缀数组三·重复旋律

    后缀数组三·重复旋律3 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi ...

  5. hihocoder #1415 : 后缀数组三·重复旋律3

    #1415 : 后缀数组三·重复旋律3 Time Limit:5000ms Case Time Limit:1000ms Memory Limit:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢 ...

  6. hihoCoder_1449_后缀自动机三·重复旋律6

    #1449 : 后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...

  7. hihoCoder 后缀自动机三·重复旋律6

    后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi ...

  8. hiho一下123周 后缀数组四·重复旋律

    后缀数组四·重复旋律4 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi ...

  9. hiho一下121周 后缀数组二·重复旋律2

    后缀数组二·重复旋律2 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi ...

随机推荐

  1. python学习:99乘法口诀

    #!/usr/bin/python   for i in xrange(1,10):     for j in xrange(1,i+1):         print "%s*%s=%s& ...

  2. Linux ipip隧道及实现

    一.IP隧道技术 IP隧道技术:是路由器把一种网络层协议封装到另一个协议中以跨过网络传送到另一个路由器的处理过程.IP 隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可 ...

  3. img alt与title的区别

    前端 alt是图片加载不出来时候,对图片的文本替代 title 是鼠标放在图片上时,对图片的进一步说明 seo 搜索引擎对图片意思的理解主要靠 alt

  4. Hibernate自动生成实体类注解(转)

    常用的hibernate annotation标签如下: @Entity --注释声明该类为持久类.将一个Javabean类声明为一 个实体的数据库表映射类,最好实现序列化.此时,默认情况下,所有的类 ...

  5. Linux常见目录及其作用

    在Linux操作系统中,所有文件和目录都被组织成一个以根节点开始的倒置的树状结构.如下图 系统一般以 / 来表示根目录.在根目录之下的可以是目录也可以是文件,而每一个目录中又可以包含子目录文件.如此反 ...

  6. pro asp.net mvc 5笔记

    1.Ninject条件绑定方法When(predicate)WhenClassHas<T>()WhenInj ectedInto<T>()例: kernel.Bind<I ...

  7. sql必知必会笔记

    1.DISTINCT 用于剔除重复的值, 如果后跟多个列, 则要求所有列的值都相同才会被剔除.    SELECT DISTINCT ven_id, prod_price FROM Products; ...

  8. 手把手教你在Ubuntu上分别安装Nginx、PHP和Mysql

    手把手教你在Ubuntu上分别安装Nginx.PHP和Mysql

  9. OO(Object Oriented)

    封装.继承.多态. 封装:隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别.封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的代码进行有 ...

  10. javascript 面向对象(多种创建对象的方式)

    创建对象 第一种:基于Object对象 var person = new Object(); person.name = 'My Name'; person.age = 18; person.getN ...