题目描述

Sandy和Sue的热衷于收集干脆面中的卡片。

然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型。

每一张卡片都由一些数字进行标记,第i张卡片的序列长度为Mi,要想兑换人物模型,首先必须要集够N张卡片,对于这N张卡片,如果他们都有一个相同的子串长度为k,则可以兑换一个等级为k的人物模型。相同的定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串。

Sandy的卡片数远远小于要求的N,于是Sue决定在Sandy的生日将自己的卡片送给Sandy,在Sue的帮助下,Sandy终于集够了N张卡片,但是,Sandy并不清楚他可以兑换到哪个等级的人物模型,现在,请你帮助Sandy和Sue,看看他们最高能够得到哪个等级的人物模型。

输入输出格式

输入格式:

第一行为一个数N,表示可以兑换人物模型最少需要的卡片数,即Sandy现在有的卡片数

第i+1行到第i+N行每行第一个数为第i张卡片序列的长度Mi,之后j+1到j+1+Mi个数,用空格分隔,分别表示序列中的第j个数

输出格式:

一个数k,表示可以获得的最高等级。

输入输出样例

输入样例#1: 复制

2
2 1 2
3 4 5 9
输出样例#1: 复制

2

说明

数据范围:

30%的数据保证n<=50

100%的数据保证n<=1000,M<=1000,2<=Mi<=101

题意:

给定几串序列,问他们最长公共子序列是多长。

思路:

类似之前做的Muisical, Themehttps://www.cnblogs.com/wyboooo/p/9865919.html

都是可以通过增加一个定值,所以只需要处理间隔。

不同的地方在于这个题目是多个不同的串。可以想到的是,是不是可以将这些串拼接起来。

拼起来就需要考虑一个问题,找到的这个串应该要避免他们跨越了拼接的那个间隔。

所以首先我们应该要用一个原来的串中从来没有出现过的字符来分隔两个串。

其次,当我们二分寻找答案的时候,应该要考虑我们找到的这个区间,他们表示的后缀的首字母也就是sa[i],是不是分别属于n个串。

所以我们要标好每个位置属于哪个串。

 #include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f const int maxn = ;
int a[maxn][maxn], s[maxn * maxn], s_len[maxn], id[maxn * maxn], vis[maxn];
int sa[maxn * maxn];
int t1[maxn * maxn], t2[maxn * maxn], c[maxn * maxn];
int rnk[maxn * maxn], height[maxn * maxn];
int n, len; void build_sa(int s[], int n, int m)
{
int i, j, p, *x = t1, *y = t2;
for(i = ; i < m; i++)c[i] = ;
for(i = ; i < n; i++)c[x[i] = s[i]]++;
for(i = ; i < m; i++)c[i] += c[i - ];
for(i = n - ; i >= ; i--)sa[--c[x[i]]] = i;
for(j = ; j <= n; j <<= ){
p = ;
for(i = n - j; i < n; i++)y[p++] = i;
for(i = ; i < n; i++)if(sa[i] >= j)y[p++] = sa[i] - j;
for(i = ; i < m; i++)c[i] = ;
for(i = ; i < n; i++)c[x[y[i]]]++;
for(i = ; i < m; i++)c[i] += c[i - ];
for(i = n - ; i >= ; i--)sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = ;
x[sa[]] = ;
for(i = ; i < n; i++){
x[sa[i]] = y[sa[i - ]] == y[sa[i]] && y[sa[i - ] + j] == y[sa[i] + j] ? p - : p++;
}
if(p >= n)break;
m = p;
}
} void get_height(int s[], int n)
{
int i, j, k = ;
for(i = ; i <= n; i++)rnk[sa[i]] = i;
for(i = ; i <= n; i++){
if(k)k--;
j = sa[rnk[i] - ];
while(s[i + k] == s[j + k])k++;
height[rnk[i]] = k;
}
}
int sta[maxn * maxn], top;
bool check(int mid)
{
while(top)vis[sta[top--]] = false;
for(int i = ; i <= len; i++){
if(height[i] < mid){
while(top)vis[sta[top--]] = false;
}
if(!vis[id[sa[i]]]){
vis[id[sa[i]]] = true;
sta[++top] = id[sa[i]];
if(top == n)return true;
}
}
return false;
} int main()
{
scanf("%d", &n);
len = ;
int mmx = -;
for(int i = ; i <= n; i++){
vis[i] = false;
scanf("%d", &s_len[i]);
for(int j = ; j <= s_len[i]; j++){
scanf("%d", &a[i][j]);
if(j)mmx = max(mmx, a[i][j] - a[i][j - ]);
}
}
int mmin = inf;
for(int i = ; i <= n; i++){
for(int j = ; j <= s_len[i]; j++){
s[++len] = a[i][j] - a[i][j - ];
id[len] = i;
mmin = min(mmin, s[len]);
}
s[++len] = ++mmx;
}
for(int i = ; i <= len; i++){
s[i] = s[i] - mmin + ;
//cout<<s[i]<<endl;
} build_sa(s, len + , );
/*for(int i = 1; i <= len; i++){
cout<<sa[i]<<endl;
}*/
get_height(s, len);
/*cout<<len<<endl;
for(int i = 2; i <= len; i++){
cout<<height[i]<<endl;
}*/
//cout<<len<<endl;
int st = , ed = len, ans = -;
while(st <= ed){
int mid = (st + ed) / ;
if(check(mid)){
st = mid + ;
ans = mid;
}
else{
ed = mid - ;
}
} printf("%d\n", ans + );
return ;
}

洛谷P2463 Sandy的卡片【后缀数组】【二分】的更多相关文章

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

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

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

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

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

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

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

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

  5. 洛谷P3763 [Tjoi2017]DNA 【后缀数组】

    题目链接 洛谷P3763 题解 后缀数组裸题 在BZOJ被卡常到哭QAQ #include<algorithm> #include<iostream> #include< ...

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

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

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

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

  8. 洛谷P4051 [JSOI2007]字符加密 后缀数组

    题目链接:https://www.luogu.org/problemnew/show/P4051 思路:我们联想求后缀数组sa的过程,发现我们在求y数组的时候(第二关键字,下标为第二关键字的排位,值为 ...

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

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

随机推荐

  1. 用python开发android应用 【转载】

    用python开发android应用 [转载] 转载自:http://www.miui.com/thread-995114-1-1.html Python是动态语言,比较简洁.Android不直接支持 ...

  2. MapWinGIS------引发类型为“System.Windows.Forms.AxHost+InvalidActiveXStateException”的异常

    转载:http://www.cnblogs.com/dzone/archive/2011/09/08/2171445.html

  3. vs2012修复问题

    多装了一个.net framework4.5.1结果vs不能拥,借用了下面这个工具将vs2012从注册表中删除了 就能重装了 http://www.auslogics.com/en/software/ ...

  4. 【AI】图像识别-物体检测-百度AI-EasyDL-NodeJS

    var https = require('https') var express = require('express'); var app = express(); var bodyParser = ...

  5. 【Android】录音暂停和继续

    https://www.2cto.com/kf/201410/347839.html http://blog.csdn.net/wanli_smile/article/details/7715030 ...

  6. [PyCharm] 设置自动启动时自动打开项目

    设置启动PyCharm时自动打开(或不打开)上次进行的项目: 选择 “Settings - General - Reopen last project on startup”,勾选该选项则启动时自动打 ...

  7. 使用taro开发钉钉的E应用报错 You are currently using minified code outside of NODE_ENV === "production". This means that you are running a slower development build of Redux. You can use loose-envify (https://git

    今天测试taro转钉钉E应用的时候,在模拟器上没事,但是在真机上却报错了: You are currently using minified code outside of NODE_ENV === ...

  8. PHP 中文字符串截取

    $str = "abcdef啊啊吧啊"; function my_sub($str, $st ,$len){ $ret = ""; for( $st; $len ...

  9. Nginx七层反向代理和负载均衡

    1.介绍 1.1 Nginx不仅是一个出色的web软件,其七层代理和负载均衡也是相当出色.Nginx做前端代理,当用户请求服务时,可以根据url进行判断,然后分配到不同的后台webserver上. 1 ...

  10. 【python问题】UnicodeEncodeError: 'ascii' codec can't encode characters in position 306-309: ordinal not in range(128)

    今天在写python爬虫的时候,遇到一个问题 UnicodeEncodeError: 'ascii' codec can't encode characters in position 306-309 ...