传送门

很容易想到,题目中的相同是指差分数组相同。

那么可以把差分数组连起来,中间加上一个没有出现过的且字典序小的数

双指针移动,用st表维护height数组中的最小值。

当然用单调队列应该也可以且更快。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 1010000 using namespace std; int n, m, t, cnt, len, ans, mx, mn = 1e9;
int pos[N], a[N / 1000], num[N / 1000], sa[N], height[N], Rank[N], b[N], x[N], y[N], d[N][22], s[N]; inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
} inline void build_sa()
{
int i, k, p;
for(i = 0; i < m; i++) b[i] = 0;
for(i = 0; i < n; i++) b[x[i] = s[i]]++;
for(i = 1; i < m; i++) b[i] += b[i - 1];
for(i = n - 1; i >= 0; i--) sa[--b[x[i]]] = i;
for(k = 1; k <= n; k <<= 1)
{
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++) b[i] = 0;
for(i = 0; i < n; i++) b[x[y[i]]]++;
for(i = 1; i < m; i++) b[i] += b[i - 1];
for(i = n - 1; i >= 0; i--) sa[--b[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]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? p - 1 : p++;
if(p >= n) break;
m = p;
}
} inline void build_height()
{
int i, j, k = 0;
for(i = 0; i < n; i++) Rank[sa[i]] = i;
for(i = 0; i < n; i++)
{
if(k) k--;
j = sa[Rank[i] - 1];
while(s[i + k] == s[j + k]) k++;
height[Rank[i]] = k;
}
} inline void build_st()
{
int i, j;
for(i = 1; i < n; i++) d[i][0] = height[i];
for(j = 1; (1 << j) < n; j++)
for(i = 1; i + (1 << j) - 1 < n; i++)
d[i][j] = min(d[i][j - 1], d[i + (1 << j - 1)][j - 1]);
} inline int query(int l, int r)
{
l++;
if(l > r) return 0;
int tmp = log2(r - l + 1);
return min(d[l][tmp], d[r - (1 << tmp) + 1][tmp]);
} inline void solve()
{
int i, j = 0;
for(i = 0; i < n; i++)
{
while(j < n && cnt < t)
{
if(!num[pos[sa[j]]]++ && pos[sa[j]]) cnt++;
j++;
}
if(cnt == t) ans = max(ans, query(i, j - 1));
if(!--num[pos[sa[i]]] && pos[sa[i]]) cnt--;
}
} int main()
{
int i, j, k;
t = read();
for(i = 1; i <= t; i++)
{
k = read();
for(j = 1; j <= k; j++) a[j] = read();
for(j = 1; j < k; j++)
{
pos[n] = i;
s[n++] = a[j + 1] - a[j];
mn = min(mn, s[n - 1]);
}
s[n++] = mx++;
}
for(i = 0; i < n; i++)
if(pos[i]) s[i] = s[i] - mn + mx, m = max(m, s[i]);
m++;
build_sa();
build_height();
build_st();
solve();
printf("%d\n", ans + 1);
return 0;
}

  

[luoguP2463] [SDOI2008]Sandy的卡片(后缀数组 + st表)的更多相关文章

  1. 【BZOJ4698】Sdoi2008 Sandy的卡片 后缀数组+RMQ

    [BZOJ4698]Sdoi2008 Sandy的卡片 Description Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡 ...

  2. 【bzoj4698】[Sdoi2008] Sandy的卡片 后缀数组

    题目描述 Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型.每一张卡片都由一些数字进行标记,第i张卡片的序列 ...

  3. BZOJ 4698: Sdoi2008 Sandy的卡片 后缀数组 + RMQ + 查分

    题目描述 Sandy和Sue的热衷于收集干脆面中的卡片. 然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型. 每一张卡片都由一些数字进行标记,第i张卡片的 ...

  4. SDOI2008 Sandy的卡片( 后缀数组 )

    求出后缀数组, 然后二分答案, 对height数组分组检验答案. 时间复杂度O(|S| log|S|) ------------------------------------------------ ...

  5. BZOJ4698: Sdoi2008 Sandy的卡片(后缀数组 二分)

    题意 题目链接 Sol 不要问我为什么发两篇blog,就是为了骗访问量 后缀数组的也比较好想,先把所有位置差分,然后在height数组中二分就行了 数据好水啊 // luogu-judger-enab ...

  6. BZOJ 4698: Sdoi2008 Sandy的卡片(后缀数组+差分+二分答案)

    传送门 解题思路 看到一个子串加一个数字到另一个子串,自然可以想到差分.然后要把所有串都拼起来,求出\(height\)数组后可以二分答案来做,每次二分一个答案后统计一下连续的\(height> ...

  7. 洛谷P2463 [SDOI2008]Sandy的卡片(后缀数组SA + 差分 + 二分答案)

    题目链接:https://www.luogu.org/problem/P2463 [题意] 求出N个串中都出现的相同子串的最长长度,相同子串的定义如题:所有元素加上一个数变成另一个,则这两个串相同,可 ...

  8. SPOJ 687 Repeats(后缀数组+ST表)

    [题目链接] http://www.spoj.com/problems/REPEATS/en/ [题目大意] 求重复次数最多的连续重复子串的长度. [题解] 考虑错位匹配,设重复部分长度为l,记s[i ...

  9. POJ 3693 Maximum repetition substring(后缀数组+ST表)

    [题目链接] poj.org/problem?id=3693 [题目大意] 求一个串重复次数最多的连续重复子串并输出,要求字典序最小. [题解] 考虑错位匹配,设重复部分长度为l,记s[i]和s[i+ ...

  10. BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay

    BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...

随机推荐

  1. [学习笔记] C++ 历年试题解析(一)--判断题

    少说话.. 程序题链接:https://www.cnblogs.com/aoru45/p/9898691.html 14级试题---选择题 1. 引用在声明时必须对其初始化,以绑定某个已经存在的变量( ...

  2. [web笔记]解决跨域问题以及axios每次提交session变化的问题

  3. PWD简介与妙用(一个免费、随时可用的Docker实验室)

    转载自 https://baiyue.one/archives/472.html 本文介绍下 PWD 的历史,并依据本站最近学习心得,经过多次尝试,终于打通了 Docker 与常规宝塔面板搭建,因此, ...

  4. Tomcat详细安装配置

    1.首先是Tomcat的获取和安装. 获取当然得上Apache的官方网站下载,开源免费,而且带宽也足够.下载会很快. 这是两种不同的下载,一个是普通安装版本,一个是解压安装版本.使用起来是一样的,只是 ...

  5. cppoop作业:Inheritance+Composition 關係下的構造和析構

    Inheritance+Composition 關係下的構造和析構 哪个的ctor先被调用. 父类先于组件类调用 构造函数

  6. vc文件操作汇总—支持wince

    一.判断文件及文件夹是否存在 // 判断文件是否存在 BOOL IsFileExist(const CString& csFile) { DWORD dwAttrib = GetFileAtt ...

  7. 并查集:CDOJ1594-老司机的奇幻漂流 (食物链)

    老司机的奇幻漂流 UESTC - 1594 Problem Description 老司机在救出了女票之后,就和她在全世界旅游,有一天,他们来到了一个神奇的小岛上. 这个小岛上有三种动物,他们互相克制 ...

  8. linux笔记(1)

    1)useradd+用户名 添加一个普通用户2)passwd+密码 为用户加密码3)su - 用户名 切换用户4)whoami 查看当前用户是什么5)$符号是普通用户#是超级用户6)mkdir /da ...

  9. 使用fio测试磁盘I/O性能

    简介: fio是测试IOPS的非常好的工具,用来对硬件进行压力测试和验证,支持13种不同的I/O引擎,包括:sync,mmap, libaio, posixaio, SG v3, splice, nu ...

  10. Netcore 基础之TagHelper知识

    饮水思源,来自:http://www.cnblogs.com/liontone 的BLOG中关于taghelper中的内容 概要 TagHelper是ASP.NET 5的一个新特性.也许在你还没有听说 ...