【poj1743】Musical Theme 【后缀自动机】
题意
给出一个n个数字的序列,找出相同变化趋势且不重叠的两个最长子串。
分析
这个题以前应该用后缀数组+二分做过。学了后缀自动机后可以用后缀自动机搞一下。
先差分,然后把查分后的数组建SAM。然后对于每个状态记录一个l[u],和r[u],分别代表right集合中,最大的v和最小的v。(这里如果不明白可以去看clj的课件)。
然后对于每个状态,当这个状态cnt[u]>=2的时候,说明有两个以上的子串,然后min(st[u].len,r[u]-l[u])就是这个状态最长不重叠相同子串的长度。
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
const int maxn=+;
const int INF=;
int s[maxn],a[maxn],n;
struct state{
int len,link;
int next[];
}st[*maxn];
int last,cur,sz;
int cnt[*maxn],l[*maxn],r[*maxn],c[*maxn];
void init(){
sz=;
last=cur=;
st[].len=;
st[].link=-;
memset(st[].next,,sizeof(st[].next));
} void build_sam(int c,int pos){
cur=sz++;
st[cur].len=st[last].len+;
cnt[cur]=;
l[cur]=r[cur]=pos;
memset(st[cur].next,,sizeof(st[cur].next));
int p;
for(p=last;p!=-&&st[p].next[c]==;p=st[p].link)
st[p].next[c]=cur;
if(p==-)
st[cur].link=;
else{
int q=st[p].next[c];
if(st[q].len==st[p].len+)
st[cur].link=q;
else{
int clone=sz++;
cnt[clone]=r[clone]=;
l[clone]=;
st[clone].len=st[p].len+;
//printf("%d ",st[clone].len);
st[clone].link=st[q].link;
memcpy(st[clone].next,st[q].next,sizeof(st[clone].next));
for(;p!=-&&st[p].next[c]==q;p=st[p].link){
st[p].next[c]=clone;
}
st[cur].link=st[q].link=clone;
}
}
last=cur;
}
int cmp(int a,int b){
return st[a].len>st[b].len;
} int ans=;
int main(){
while(scanf("%d",&n)!=EOF&&n){
for(int i=;i<=n;i++){
scanf("%d",&s[i]);
a[i]=s[i]-s[i-];
}
init();
for(int i=;i<=n;i++){
build_sam(a[i]+,i);
//printf("%d ",a[i]);
}
// for(int i=0;i<sz;i++)
// printf("%d ",st[i].len);
// printf("\n");
for(int i=;i<sz;i++)
c[i]=i;
sort(c,c+sz,cmp);
ans=;
for(int i=;i<sz;i++){
int o=c[i];
if(st[o].link!=-){
cnt[st[o].link]+=cnt[o];
l[st[o].link]=min(l[st[o].link],l[o]);
r[st[o].link]=max(r[st[o].link],r[o]);
}
// printf("%d %d %d %d\n",cnt[o],st[o].len,l[o],r[o]);
if(cnt[o]>=&&min(st[o].len,r[o]-l[o])>=){
//printf("%d %d\n",l[o],r[o]);
ans=max(ans,min(st[o].len,r[o]-l[o]));
}
}
if(ans<)
printf("0\n");
else
printf("%d\n",ans+);
}
return ;
}
【poj1743】Musical Theme 【后缀自动机】的更多相关文章
- POJ1743 Musical Theme [后缀自动机]
题意:不重叠最长重复子串 后缀数组做法:http://www.cnblogs.com/candy99/p/6227659.html 后缀自动机的话,首先|Right|>=2 然后min(t[u] ...
- POJ1743 Musical Theme —— 后缀数组 重复出现且不重叠的最长子串
题目链接:https://vjudge.net/problem/POJ-1743 Musical Theme Time Limit: 1000MS Memory Limit: 30000K Tot ...
- POJ1743 Musical Theme [后缀数组]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- POJ1743 Musical Theme [后缀数组+分组/并查集]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- poj 1743 Musical Theme 后缀自动机/后缀数组/后缀树
题目大意 直接用了hzwer的题意 题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题."主题&qu ...
- POJ1743 Musical Theme(后缀数组 二分)
Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 33462 Accepted: 11124 Description A m ...
- POJ-1743 Musical Theme(后缀数组)
题目大意:给一个整数序列,找出最长的连续变化相同的.至少出现两次并且不相重叠一个子序列. 题目分析:二分枚举长度进行判定. 代码如下: # include<iostream> # incl ...
- poj1743 Musical Theme 后缀数组的应用(求最长不重叠重复子串)
题目链接:http://poj.org/problem?id=1743 题目理解起来比较有困难,其实就是求最长有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1 ...
- POJ1743 Musical Theme (后缀数组 & 后缀自动机)最大不重叠相似子串
A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...
- poj1743 Musical Theme【后缀数组】【二分】
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 35044 Accepted: 11628 D ...
随机推荐
- 利用 netsh 给 mysql 开启多端口监听
利用 netsh 给 mysql 开启多端口监听 标题党,实际并不是真的多端口监听,只是端口转发而已. 由于某种特殊原因需要 mysql 服务器多个端口监听. mysql 服务器本身是不支持的,但可以 ...
- windows环境vagrant修改静态资源文件,centos虚拟机中nginx的web环境下不生效
最近上手krpano,本地修改了krpano.html文件或者xml文件,在虚拟机环境打开文件是修改过来了,在nginx中就是不生效. 修改nginx.conf中http{}中的 sendfile ...
- 微信卡券开发,代金券修改卡券信息返回40145错误码: invalid update! Can not both set PayCell and CenterCellInfo(include: center_title, center_sub_title, center_url). hint: [DZ9rna0637ent1]
修改代金券,接口返回的数组是这样的内容 Array ( [errcode] => 40145 [errmsg] => invalid update! Can not both set ...
- 结合示例说明C++中const和指针结合时怎么理解
在之前随笔<C++中const使用要点(一)>中简单叙述了const int*.int* const和const int* const的区别,记住三句话就能在实际运用时用对,但是看书时发现 ...
- 确保nginx安全的10个技巧
Nginx是当今最流行的Web服务器之一.它为世界上7%的web流量提供服务而且正在以惊人的速度增长.它是个让人惊奇的服务器,我愿意部署它. 下面是一个常见安全陷阱和解决方案的列表,它可以辅助来确保你 ...
- Netty--JDK序列化编解码传输对象
使用JDK序列化不需要额外的类库,只需要实现Serializable即可,但是序列化之后的码流只有Java才能反序列化,所以它不是跨语言的,另外由于Java序列化后码流比较大,效率也不高,所以在RPC ...
- java代码----对于数据类型Integer
总结: 主要是方法的理解 老师曾经说过final 和fianlly的区别 我自己的理解就是 如果一个类的前面定义了final,那么它就不能被继承,派生子类,对于方法,那么方法就不能改变,变量前面也是必 ...
- 自动化运维工具Ansible的简单使用
一 基础使用 1. 简介ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统配置. ...
- Linux: su sudo sudoer
日常操作中为了避免一些误操作,更加安全的管理系统,通常使用的用户身份都为普通用户,而非root.当需要执行一些管理员命令操作时,再切换成root用户身份去执行. 普通用户切换到root用户的方式有:s ...
- 用VIM设置UTF-8编码的BOM标记
1.去掉BOM标记: :set nobomb 2.加上BOM标记: :set bomb 3.查询当前UTF-8编码的文件是否有BOM标记: :set bomb? 4.更高级一点的: :%!xxd &q ...