poj1743

题意

给出一个数字序列(串),现在要去寻找一个满足下列条件的子串:

  1. 长度不小于 5
  2. 存在重复的子串(如果把一个子串的所有数字都加上或减去一个值,与另一子串的数字对应相同,我们称它们重复)
  3. 重复的子串之间不能重叠

分析

把相邻的数字作差(后面的减前面的)得到一个新的数列。

那么我们去二分答案 m ,判断串上是否存在两个不重叠但是完全相同的长度为 m 的子串。

判断不重叠:在分组时,记录最大最小 sa 值,如果最大减最小的值大于 m ,说明不重叠(这样其实是要至少隔一个位置,注意最后答案加 1)。

code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 2e4 + 10;
const int INF = 1e9;
int s[MAXN];
int sa[MAXN], t[MAXN], t2[MAXN], c[MAXN], n; // n 为 字符串长度 + 1,s[n - 1] = 0 int rnk[MAXN], height[MAXN];
// 构造字符串 s 的后缀数组。每个字符值必须为 0 ~ m-1
void build_sa(int m) {
int i, *x = t, *y = t2;
for(i = 0; i < m; i++) c[i] = 0;
for(i = 0; i < n; i++) c[x[i] = s[i]]++;
for(i = 1; i < m; i++) c[i] += c[i - 1];
for(i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
for(int k = 1; k <= n; k <<= 1) {
int p = 0;
for(i = n - k; i < n; i++) y[p++] = i;
for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = 0; i < m; i++) c[i] = 0;
for(i = 0; i < n; i++) c[x[y[i]]]++;
for(i = 0; i < m; i++) c[i] += c[i - 1];
for(i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = 1; x[sa[0]] = 0;
for(i = 1; i < n; i++)
x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
if(p >= n) break;
m = p;
}
}
void getHeight() {
int i, j, k = 0;
for(i = 0; i < n; i++) rnk[sa[i]] = i;
for(i = 0; i < n - 1; i++) {
if(k) k--;
j = sa[rnk[i] - 1];
while(s[i + k] == s[j + k]) k++;
height[rnk[i]] = k;
}
}
int check(int m) {
int cnt = 0, mx = sa[1], mn = sa[1];
for(int i = 2; i < n; i++) {
while(i < n && height[i] >= m) {
mx = max(mx, sa[i]);
mn = min(mn, sa[i]);
i++;
}
if(mx - mn > m) return 1;
mx = sa[i]; mn = sa[i];
}
return 0;
}
int main() {
while(~scanf("%d", &n) && n) {
for(int i = 0; i < n; i++) {
scanf("%d", &s[i]);
}
for(int i = 0; i < n - 1; i++) {
s[i] = s[i + 1] - s[i] + 100;
}
s[n - 1] = 0;
build_sa(200);
getHeight();
int l = 0, r = n, ans = 0, mid;
while(l <= r) {
mid = (l + r) / 2;
if(check(mid)) { l = mid + 1; ans = mid; }
else r = mid - 1;
}
if(ans < 4) ans = 0;
else ans++;
printf("%d\n", ans);
}
return 0;
}

poj1743(后缀数组)的更多相关文章

  1. [Poj1743] [后缀数组论文例题] Musical Theme [后缀数组不可重叠最长重复子串]

    利用后缀数组,先对读入整数处理str[i]=str[i+1]-str[i]+90这样可以避免负数,计算Height数组,二分答案,如果某处H<lim则将H数组分开,最终分成若干块,判断每块中是否 ...

  2. poj1743 后缀数组求不可重叠的重复出现的子串最长长度

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 25348   Accepted: 8546 De ...

  3. Poj1743 (后缀数组)

    #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using ...

  4. Musical Theme poj1743(后缀数组)

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 16757   Accepted: 5739 De ...

  5. poj1743 后缀数组, poj挂了 存个代码

    #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk mak ...

  6. 【POJ1743】Musical Theme(后缀数组)

    [POJ1743]Musical Theme(后缀数组) 题面 洛谷,这题是弱化版的,\(O(n^2)dp\)能过 hihoCoder 有一点点区别 POJ 多组数据 题解 要求的是最长不可重叠重复子 ...

  7. POJ1743 Musical Theme —— 后缀数组 重复出现且不重叠的最长子串

    题目链接:https://vjudge.net/problem/POJ-1743 Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Tot ...

  8. P2743(poj1743) Musical Themes[差分+后缀数组]

    P2743 乐曲主题Musical Themes(poj1743) 然后呢这题思路其实还是蛮简单的,只是细节特别多比较恶心,忘记了差分带来的若干疏漏.因为转调的话要保证找到相同主题,只要保证一段内相对 ...

  9. POJ1743 Musical Theme 最长重复子串 利用后缀数组

    POJ1743 题目意思是求不重叠的最长相同变化的子串,输出该长度 比如1 2 3 4 5 6 7 8 9 10,最长长度为5,因为子串1 2 3 4 5 和 6 7 8 9 10变化都一样的 思路: ...

随机推荐

  1. 《Cracking the Coding Interview》——第10章:可扩展性和存储空间限制——题目7

    2014-04-24 22:06 题目:搜索引擎问题,如果有一列100台服务器的集群,用来响应查询请求,你要如何设计query分发和cache策略? 解法:query分发可以用计算数字签名并对机器数取 ...

  2. Pascal小游戏 井字棋

    一个很经典的井字棋游戏 Pascal源码Chaobs奉上 注意:1.有的FP版本不支持汉语,将会出现乱码.2.别想赢电脑了,平手不错了. 井字过三关: program TicTacToe; uses ...

  3. 《算法》C++代码 前言

    现在大二正在上<数据结构>课,课内的书上代码实现很喜欢无脑用类.变量名字很长,而且常常实现太繁琐,并且代码有些无法运行,这些对于老手无所谓,但初学者看起来却会很不舒服.因此写点自己的代码, ...

  4. 使用 JsonPath 完成接口自动化测试中参数关联和数据验证(Python语言)

    背景: 接口自动化测试实现简单.成本较低.收益较高,越来越受到企业重视 restful风格的api设计大行其道 json成为主流的轻量级数据交换格式 痛点: 接口关联 也称为关联参数.在应用业务接口中 ...

  5. Oracle 学习---- 练习语法 循环( loop end loop; for ;while; if elsif end if )

    /*--set serveroutput on;declare mynum number(3) :=0; tip varchar2(10):='结果是 ';begin mynum:=10+100; d ...

  6. 一步步精通NodeJs的简单实例

    一步一步完成nodejs+express+mysql的简单实例开发 1.使用express创建简单web服务器 项目文件下安装express,这个不多说,很简单,直接在项目目录下运行 npm inst ...

  7. maven中mapper.xml不发布的问题

    在自定义的包中定义了mapper.xml然后利用mybatis的扫描包形式来动态创建mapper 开启工程报错: 说无效的绑定 原因: 发布的war中,工程包中的mapper根本就没有出现在class ...

  8. GCC特性之__init修饰解析 - kasalyn的专栏 - 博客频道 - CSDN.NET

    , GCC特性之__init修饰解析 - kasalyn的专栏 - 博客频道 - CSDN.NET.MathJax_Hover_Frame {border-radius: .25em; -webkit ...

  9. JS计算器(自制)

    <!doctype html><html><header><meta charset="utf-8"><script src= ...

  10. 【bzoj5055】膜法师 离散化+树状数组

    题目描述 给定一个序列$a$,求满足$i<j<k$且$a_i<a_j<a_k$的三元组$(i,j,k)$的个数. 输入 第一行1个数 n 第二行n个数 a_i 输出 一个数,表 ...