POJ 1743 Musical Theme【SAM】
POJ1743 Musical Theme
要找长度\(\ge 5\)且出现次数\(\ge 2\)并且第一次出现和最后一次出现不重叠的最长子串。
题目条件中,如果对于两个串,在一个串的每个数上都加上相同的数之后可以得到另一个串,那么这个两个串可以被是相同的。
首先我们先得到差分数组,然后要求的就是差分数组中长度\(\ge 4\)且出现次数\(\ge 2\)并且第一次出现和最后一次出现不重叠的最长子串
我们需要知道的是每个等价类中终点的最左端和最右端的位置,即(\(firstpos,lastpos\)),每次新加入一个字符所得到的等价类其\(firstpos\)和\(lastpos\)必然为当前的下标,当构造完\(SAM\)之后,由于\(parent\)树的性质,\(link[u]\)所表示的等价类必然是\(u\)所表示的等价类的后缀,所以可以得到:\(lastpos[u] = max_{v\in children} lastpos[v]\)其中\(v\)是\(u\)在\(parent\)树中的儿子,而\(firstpos\)必然一直保持不变。
可以用拓扑排序然后倒序遍历来代替建\(parent\)树然后\(dfs\),拓扑排序即为按\(len\)排序,用基数排序即可
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
#include<stack>
using namespace std;
void ____(){ ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); }
const int MAXN = 1e5+7;
int n,A[MAXN];
struct SAM{
int len[MAXN],link[MAXN],firstpos[MAXN],lastpos[MAXN],ch[MAXN][180],tot,last,cnt[MAXN],c[MAXN],sa[MAXN];
void init(){ link[tot = last = cnt[0] = len[0] = 0] = -1; memset(ch[0],0,sizeof(ch[0])); }
void extend(int x){
int np = ++tot, p = last; firstpos[tot] = lastpos[tot] = len[tot] = len[last] + 1;
memset(ch[tot],0,sizeof(ch[tot])); cnt[tot] = 1;
while(p!=-1 and !ch[p][x]){
ch[p][x] = np;
p = link[p];
}
if(p==-1) link[np] = 0;
else{
int q = ch[p][x];
if(len[p]+1==len[q]) link[np] = q;
else{
int clone = ++tot;
cnt[clone] = 0;
firstpos[clone] = firstpos[q];
lastpos[clone] = lastpos[q];
len[clone] = len[p] + 1;
for(int i = 0; i < 180; i++) ch[clone][i] = ch[q][i];
link[clone] = link[q];
while(p!=-1 and ch[p][x]==q){
ch[p][x] = clone;
p = link[p];
}
link[np] = link[q] = clone;
}
}
last = np;
}
int solve(){
for(int i = 0; i <= n; i++) c[i] = 0;
for(int i = 0; i <= tot; i++) c[len[i]]++;
for(int i = 1; i <= n; i++) c[i] += c[i-1];
for(int i = tot; i >= 0; i--) sa[c[len[i]]--] = i;
int ret = 0;
for(int i = tot+1; i >= 1; i--){ //这里要注意,基数排序的时候是0~tot,所以排名最后的是tot+1
int u = sa[i];
cnt[link[u]] += cnt[u];
lastpos[link[u]] = max(lastpos[link[u]],lastpos[u]);
ret = max(ret,min(len[u] + 1,lastpos[u]-firstpos[u]));
}
if(ret<5) ret = 0;
return ret;
}
}sam;
void solve(){
for(int i = 1; i <= n; i++) scanf("%d",&A[i]);
for(int i = 1; i < n; i++) A[i] = A[i+1] - A[i] + 88;
sam.init(); for(int i = 1; i < n; i++) sam.extend(A[i]);
printf("%d\n",sam.solve());
}
int main(){
while(scanf("%d",&n)!=EOF and n) solve();
return 0;
}
POJ 1743 Musical Theme【SAM】的更多相关文章
- POJ 1743 Musical Theme 【后缀数组 最长不重叠子串】
题目冲鸭:http://poj.org/problem?id=1743 Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Su ...
- Poj 1743——Musical Theme——————【后缀数组,求最长不重叠重复子串长度】
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 22499 Accepted: 7679 De ...
- poj 1743 Musical Theme【后缀自动机】
不是很神的一道题,一般. 先差分,最后答案需要+1. 一个right集的len即为该right集的最长相同后缀,考虑到不能重复,所以处理一下该right集的最大与最小的ri,最后答案ans=max(a ...
- poj 1743 Musical Theme【二分+SA】
差分,然后二分长度mid,判断是把height按照min不小于mid分组,取最大最小的sa位置看是否>=mid即可,注意差分后最后答案要+1 #include<iostream> # ...
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)(转)
永恒的大牛,kuangbin,膜拜一下,Orz 链接:http://www.cnblogs.com/kuangbin/archive/2013/04/23/3039313.html Musical T ...
- poj 1743 Musical Theme(最长重复子串 后缀数组)
poj 1743 Musical Theme(最长重复子串 后缀数组) 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复 ...
- Poj 1743 Musical Theme (后缀数组+二分)
题目链接: Poj 1743 Musical Theme 题目描述: 给出一串数字(数字区间在[1,88]),要在这串数字中找出一个主题,满足: 1:主题长度大于等于5. 2:主题在文本串中重复出现 ...
- POJ 1743 Musical Theme 后缀数组 最长重复不相交子串
Musical ThemeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1743 Description ...
- POJ 1743 Musical Theme(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=1743 [题目大意] 给出一首曲子的曲谱,上面的音符用不大于88的数字表示, 现在请你确定它主旋律的长度,主旋律指的是出现超过一次, ...
随机推荐
- 【C++】《C++ Primer 》第十三章
第十三章 拷贝控制 定义一个类时,需要显式或隐式地指定在此类型地对象拷贝.移动.赋值和销毁时做什么. 一个类通过定义五种特殊的成员函数来控制这些操作.即拷贝构造函数(copy constructor) ...
- 使用 C# 9 的records作为强类型ID - 路由和查询参数
上一篇文章,我介绍了使用 C# 9 的record类型作为强类型id,非常简洁 public record ProductId(int Value); 但是在强类型id真正可用之前,还有一些问题需要解 ...
- html2canvas canvas webgl 截图透明空🤣
1. React用这个插件html2canvas完成div截图功能,div里面嵌套canvas,返回base64是透明图片. html2canvas(document.getElementById(& ...
- 【Azure Developer】解决Azure Key Vault管理Storage的示例代码在中国区Azure遇见的各种认证/授权问题 - C# Example Code
问题描述 使用Azure密钥保管库(Key Vault)来托管存储账号(Storage Account)密钥的示例中,从Github中下载的示例代码在中国区Azure运行时候会遇见各种认证和授权问题, ...
- 汇编学习笔记——DOS及DEBUG介绍
转自:https://www.shiyanlou.com/courses/running/332 一.课程简介 声明:该课程基于<汇编语言(第2版)>郑晓薇 编著,机械工业出版社.本节实验 ...
- ALV中layout布局控制详解
参数的结构为SLIS_LAYOUT_ALV.结构中比较常用的字段如下: no_colhead 隐藏列标题 值为X或空 no_hotspot headings不作为热 ...
- uni-app开发经验分享二十一: 图片滑动解锁插件制作解析
在开发用户模块的时候,相信大家都碰到过一个功能,图片滑动解锁后发送验证码,这里分享我用uni-app制作的一个小控件 效果如下: 需要如下图片资源 template <template> ...
- STL_list容器
一.List简介 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. 链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每 ...
- 前端工程构建之谈:gulp3要不要升级到Gulp4
关于升级还是不升级,这是一个哲学问题. gulp4的语法更加现代,支持ES6的大部分写法,使用exports的方式去暴露任务组合,更加灵活和便捷. gulp4同时也提供了很多强大的API,例如para ...
- js中的事件委托(事件代理)详解
本文转载:https://www.cnblogs.com/liugang-vip/p/5616484.html#!comments js中的事件冒泡.事件委托是js 中一些需要注意的小知识点,这里结合 ...