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

--------------------------------------------------------------------------------

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
const int maxn = 1009;
const int maxN = 1000009;
 
inline int read() {
char c = getchar();
for(; !isdigit(c); c = getchar());
int ret = 0;
for(; isdigit(c); c = getchar())
ret = ret * 10 + c - '0';
return ret;
}
 
bool vis[maxn];
int str[maxn][maxn], len[maxn], n, Top;
int S[maxN], Id[maxN], stk[maxN], N;
int cnt[maxN], Sa[maxN], Height[maxN], Rank[maxN];
 
void Build(int m) {
int *x = Height, *y = Rank;
for(int i = 0; i < m; i++) cnt[i] = 0;
for(int i = 0; i < N; i++) cnt[x[i] = S[i]]++;
for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];
for(int i = N; i--; ) Sa[--cnt[x[i]]] = i;
for(int k = 1, p = 0; k <= N; k <<= 1, p = 0) {
for(int i = N - k; i < N; i++) y[p++] = i;
for(int i = 0; i < N; i++)
if(Sa[i] >= k) y[p++] = Sa[i] - k;
for(int i = 0; i < m; i++) cnt[i] = 0;
for(int i = 0; i < N; i++) cnt[x[y[i]]]++;
for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];
for(int i = N; i--; ) Sa[--cnt[x[y[i]]]] = y[i];
swap(x, y);
p = 1;
x[Sa[0]] = 0;
for(int i = 1; i < N; i++) {
if(y[Sa[i]] != y[Sa[i - 1]] || y[Sa[i] + k] != y[Sa[i - 1] + k]) p++;
x[Sa[i]] = p - 1;
}
if(p >= N) break;
m = p;
}
for(int i = 0; i < N; i++) Rank[Sa[i]] = i;
Height[0] = 0;
for(int i = 0, h = 0; i < N; i++) if(Rank[i]) {
if(h) h--;
while(S[i + h] == S[Sa[Rank[i] - 1] + h]) h++;
Height[Rank[i]] = h;
}
}
 
void Init() {
int mn = 1 << 30, mx = -1 << 30;
n = read();
for(int i = 0; i < n; i++) {
len[i] = read();
for(int j = 0; j < len[i]; j++) str[i][j] = read();
for(int j = len[i]; --j; ) {
str[i][j] -= str[i][j - 1];
mn = min(mn, str[i][j]);
mx = max(mx, str[i][j]);
}
}
N = 0;
for(int i = 0; i < n; i++) {
for(int j = 1; j < len[i]; j++) {
S[N] = str[i][j] - mn + n;
Id[N++] = i;
}
S[N] = n - i - 1;
Id[N++] = n;
}
Build(mx - mn + n + 1);
memset(vis, 0, sizeof vis);
vis[n] = 1;
Top = 0;
}
 
bool chk(int v) {
while(Top) vis[stk[--Top]] = 0;
for(int i = 1; i < N; i++) if(Height[i] >= v) {
if(!vis[Id[Sa[i - 1]]])
vis[stk[Top++] = Id[Sa[i - 1]]] = 1;
if(!vis[Id[Sa[i]]])
vis[stk[Top++] = Id[Sa[i]]] = 1;
if(Top >= n) return true;
} else {
while(Top) vis[stk[--Top]] = 0;
}
return false;
}
 
void Work() {
int l = 1, r = maxN, ans = 0;
while(l <= r) {
int m = (l + r) >> 1;
if(chk(m)) {
ans = m, l = m + 1;
}
else
r = m - 1;
}
printf("%d\n", ++ans);
}
 
int main() {
Init();
Work();
return 0;
}

--------------------------------------------------------------------------------

SDOI2008 Sandy的卡片( 后缀数组 )的更多相关文章

  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. BZOJ4698: Sdoi2008 Sandy的卡片(后缀数组 二分)

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

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

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

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

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

  7. 【BZOJ-4698】Sandy的卡片 后缀数组

    4698: Sdoi2008 Sandy的卡片 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 140  Solved: 55[Submit][Stat ...

  8. BZOJ 4698: Sdoi2008 Sandy的卡片 [后缀自动机]

    4698: Sdoi2008 Sandy的卡片 题意:差分后就是多个串LCS SAM+map大法好 模板打错 智力-2 #include <iostream> #include <c ...

  9. LG2463/BZOJ4698 「SDOI2008」Sandy的卡片 后缀数组

    问题描述 LG2463 BZOJ4698 题解 看到\(n\)个数串,一开始不太好处理,可以很容易想到把这\(n\)个数串连到一起,形成一个大串,但是每个串之间不容易处理. 经过思考,想到在每个串中间 ...

随机推荐

  1. 解密yii中CModule::_components和CModule::_componentConfig

    array CModule::_components 所有组件对象(CComponent的子类)将作为键值存在该数组中, 键名是定义该组件时使用的键名.例如: protected function r ...

  2. 我的经常使用linux小命令

        这里并非系统具体介绍每个Linux命令,不过记录本人在平时工作中经经常使用到的一些比較基础的命令及相关的參数,同一时候用了一些简单的样例来说明这些命令的用途,以及怎样用多种命令来实现同一种功能 ...

  3. oj 小黑华丽的逆袭机会

    Problem H: 小黑华丽的逆袭机会 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 79  Solved: 7 [Submit][Status][ ...

  4. IOS 8弃用api

    IOS 8弃用api 下面api是弃用: 的 UIApplication 方法和属性注冊通知. 使用新的API. 的 uiviewcontroller 面向接口的方法和属性. 中描写叙述的特征和大小类 ...

  5. 重写系统中的UINavigationController 返回按钮的事件

    .扩展UIviewController UIViewController+BackButtonHandler.h #import <UIKit/UIKit.h> @protocol Bac ...

  6. IIS的安装

    xp上好像只能装IIS5,IIS6根本就装不了

  7. 用iframe框架,登录过期后登录框在框架里加载的问题

    就是登录界面出现在iframe的框架里,而不是整个页面都跳转,找到了一个JS的解决方法,只要把下面的代码放在登录界面的<head></head>里就行了. <script ...

  8. ##DAY3 自定义视图、视图控制器、视图控制器指定视图、loadView、 viewDidLoad、MVC、屏幕旋转、内存警告

    ##DAY3 自定义视图.视图控制器.视图控制器指定视图.loadView. viewDidLoad.MVC.屏幕旋转.内存警告 #pragma mark ———————自定义视图的步骤 —————— ...

  9. 关于 css padding 的使用 padding会将使用该属性的元素撑开

    .right_img_box{ width:300px; height:250px; border:1px solid #c9c9c9; margin-bottom:15px; background: ...

  10. php7 install memcache extension

    #download source code package from git $ git clone https://github.com/websupport-sk/pecl-memcache.gi ...