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】的更多相关文章

  1. POJ 1743 Musical Theme 【后缀数组 最长不重叠子串】

    题目冲鸭:http://poj.org/problem?id=1743 Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Su ...

  2. Poj 1743——Musical Theme——————【后缀数组,求最长不重叠重复子串长度】

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22499   Accepted: 7679 De ...

  3. poj 1743 Musical Theme【后缀自动机】

    不是很神的一道题,一般. 先差分,最后答案需要+1. 一个right集的len即为该right集的最长相同后缀,考虑到不能重复,所以处理一下该right集的最大与最小的ri,最后答案ans=max(a ...

  4. poj 1743 Musical Theme【二分+SA】

    差分,然后二分长度mid,判断是把height按照min不小于mid分组,取最大最小的sa位置看是否>=mid即可,注意差分后最后答案要+1 #include<iostream> # ...

  5. POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)(转)

    永恒的大牛,kuangbin,膜拜一下,Orz 链接:http://www.cnblogs.com/kuangbin/archive/2013/04/23/3039313.html Musical T ...

  6. poj 1743 Musical Theme(最长重复子串 后缀数组)

    poj 1743 Musical Theme(最长重复子串 后缀数组) 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复 ...

  7. Poj 1743 Musical Theme (后缀数组+二分)

    题目链接: Poj  1743 Musical Theme 题目描述: 给出一串数字(数字区间在[1,88]),要在这串数字中找出一个主题,满足: 1:主题长度大于等于5. 2:主题在文本串中重复出现 ...

  8. POJ 1743 Musical Theme 后缀数组 最长重复不相交子串

    Musical ThemeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1743 Description ...

  9. POJ 1743 Musical Theme(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=1743 [题目大意] 给出一首曲子的曲谱,上面的音符用不大于88的数字表示, 现在请你确定它主旋律的长度,主旋律指的是出现超过一次, ...

随机推荐

  1. linux mysql source 导入大文件报错解决办法

    找到mysql的配置文件目录 my.cnf interactive_timeout = 120wait_timeout = 120max_allowed_packet = 500M 在导入过程中可能会 ...

  2. python中列表的insert和append的效率对比

    python中insert和append方法都可以向列表中插入数据只不过append默认插入列表的末尾,insert可以指定位置插入元素. 我们来测试一下他俩插入数据的效率: 测试同时对一个列表进行插 ...

  3. Python基础语法2-数据类型

    一,数字. 2. 字符串类型 3.列表 4.元组 5.集合 6.字典 7.数据类型转换: 8.序列操作

  4. 改进你的c#代码的5个技巧(四)

    像每一篇文章一样,我会重复几行.我在我的Core i3 CPU.4GB主内存和Windows 7平台上测试了以下代码.如果你在不同的硬件配置或使用不同的平台,那么你的输出可能会随着我的输出屏幕而变化, ...

  5. [mysql]ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value

    转载自:http://www.cnblogs.com/joeblackzqq/p/4526589.html From: http://m.blog.csdn.net/blog/langkeziju/1 ...

  6. python sqlite3增加表字段

    给sqlite3表格增加新字段,要注意大小写,要不然不成功. 一开始这样写,不成功! 后面规范写,按大小写严格规范写! 成功了!现在查看新增加的字段commit: 仔细看,这下全部小写,括表名称.co ...

  7. VKM5对应的BAPI或者函数

    在业务上,当一个交货单创建后,可能需要使用事物VKM5进行批准(解冻)才能做后续的捡配,发货过账等操作,通过搜索引擎发现,很多人也都会问是否有对应的bapi或者函数,替代VKM5,能够自开发程序进行批 ...

  8. DOCKER 安装步骤-最靠谱的笔记

    一.系统环境规划 服务器名 项目名称 docker 操作系统 CentOS Linux release 7.1.1503 (Core) Docker 版本 17.03.2-ce   二.Docker ...

  9. 边缘计算k8s集群SuperEdge初体验

    前言 手上一直都有一堆的学生主机,各种各样渠道途径拿来的机器. 一直管理里面都比较蛋疼,甚至也不太记得住它们在哪是什么IP,管理起来很是头疼. 有阵子空闲的时候想折腾了一下边缘计算集群方案. 希望能把 ...

  10. Cisco IOS

    IOS Internetwork Operating System 互联网操作系统(基于UNIX系统) Cisco IOS 软件提供多种网络服务进而支持各种网络应用. Cisco IOS用户界面的基本 ...