http://www.lydsy.com/JudgeOnline/problem.php?id=4698

https://www.luogu.org/problemnew/show/P2463#sub

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

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

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

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

如果你做过POJ2774:Long Long MessagePOJ1743:Musical Theme的话,这道题想起来就很容易了。

将所有数差分后接起来(中间加一个大数作为分隔符),后缀数组和height数组预处理,然后二分答案,按照height分组找是否存在。

PS:差分处理具体看POJ1743:Musical Theme。

(吐槽:最开始我还想把所有数段的区间记下来,然后用log查找一个后缀属于哪个串,越想越不对劲看了题解,果然我还是太naive了,直接开个id数组记录每个数属于哪个数段就行了吗!)

(果然我容易思维定式。)

(姑且也算是不看题解1A233。)

#include<cstdio>
#include<cmath>
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
typedef long long ll;
const int N=1e6+;
const int big=;
int s[N],a[N],cnt=big*+;
int n,m,t,rk[N],sa[N],w[N],height[N],id[N];
bool in[];
inline bool pan(int *x,int i,int j,int k){
int ti=i+k<n?x[i+k]:-;
int tj=j+k<n?x[j+k]:-;
return ti==tj&&x[i]==x[j];
}
void SA_init(){
int *x=rk,*y=height,r=cnt;
for(int i=;i<r;i++)w[i]=;
for(int i=;i<n;i++)w[s[i]]++;
for(int i=;i<r;i++)w[i]+=w[i-];
for(int i=n-;i>=;i--)sa[--w[s[i]]]=i;
r=;x[sa[]]=;
for(int i=;i<n;i++)
x[sa[i]]=s[sa[i]]==s[sa[i-]]?r-:r++;
for(int k=;r<n;k<<=){
int yn=;
for(int i=n-k;i<n;i++)y[yn++]=i;
for(int i=;i<n;i++)
if(sa[i]>=k)y[yn++]=sa[i]-k;
for(int i=;i<r;i++)w[i]=;
for(int i=;i<n;i++)w[x[y[i]]]++;
for(int i=;i<r;i++)w[i]+=w[i-];
for(int i=n-;i>=;i--)sa[--w[x[y[i]]]]=y[i];
swap(x,y);r=;x[sa[]]=;
for(int i=;i<n;i++)
x[sa[i]]=pan(y,sa[i],sa[i-],k)?r-:r++;
}
}
void height_init(){
int i,j,k=;
for(int i=;i<=n;i++)rk[sa[i]]=i;
for(int i=;i<n;i++){
if(k)k--;
int j=sa[rk[i]-];
while(s[i+k]==s[j+k])k++;
height[rk[i]]=k;
}
}
bool check(int k){
int sum=;
in[id[sa[]]]=;
for(int i=;i<=n;i++){
if(height[i]>=k){
if(!in[id[sa[i]]]){
sum++;
in[id[sa[i]]]=;
}
}else{
memset(in,,sizeof(in));
sum=;
in[id[sa[i]]]=;
}
if(sum==t)return ;
}
return ;
}
int main(){
scanf("%d",&t);
for(int i=;i<=t;i++){
scanf("%d",&m);
for(int j=n;j<=n+m-;j++){
scanf("%d",&a[j]);
}
for(int j=n+;j<=n+m-;j++){
s[j-]=a[j]-a[j-]+big;
id[j-]=i;
}
s[n+m-]=cnt++;
n+=m;
}
s[n++]=;
SA_init();
n--;
height_init();
int l=,r=;
while(l<r){
int mid=(l+r+)>>;
if(check(mid))l=mid;
else r=mid-;
}
printf("%d\n",l+);
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ4698 & 洛谷2463:[SDOI2008]Sandy的卡片——题解的更多相关文章

  1. 洛谷 P2463 [SDOI2008]Sandy的卡片 解题报告

    P2463 [SDOI2008]Sandy的卡片 题意 给\(n(\le 1000)\)串,定义两个串相等为"长度相同,且一个串每个数加某个数与另一个串完全相同",求所有串的最长公 ...

  2. [洛谷P2463][SDOI2008]Sandy的卡片

    题目大意:有$n$个字符串,求这$n$个字符串中最长的相似公共字串,相似的定义是加上一个数后相同 题解:差分,建广义后缀自动机,然后求出每个点在多少个字符串中出现过,若在$n$个中都出现,就更新答案 ...

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

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

  4. 洛咕 P2463 [SDOI2008]Sandy的卡片

    哈希水过. 首先这是一段delta相同的序列,按照套路差分一下,b[i]=a[i]-a[i-1],然后就是这些序列的最长公共子段 由于数据范围很小,就可以二分,枚举第一个序列的子段然后每个子序列暴力c ...

  5. luogu 2463 [SDOI2008]Sandy的卡片 kmp || 后缀数组 n个串的最长公共子串

    题目链接 Description 给出\(n\)个序列.找出这\(n\)个序列的最长相同子串. 在这里,相同定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串. 思路 参考:hzwe ...

  6. 【BZOJ4698】[SDOI2008]Sandy的卡片

    [BZOJ4698][SDOI2008]Sandy的卡片 题面 flag倒了. bzoj 洛谷 题解 首先题目的区间加很丑对吧, 将每个串差分一下,就可以转化为 求: 给定\(N\)个串,求他们的最长 ...

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

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

  8. bzoj4698 / P2463 [SDOI2008]Sandy的卡片

    P2463 [SDOI2008]Sandy的卡片 直接二分长度暴力匹配....... 跑的还挺快 (正解是后缀数组的样子) #include<iostream> #include<c ...

  9. BZOJ 4698: Sdoi2008 Sandy的卡片

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

随机推荐

  1. 分享开源的GB/T-2260国家行政区划代码

    项目中需要用到省市数据,在网上搜了一下,很多旧数据,稍微新一点的下载就要积分.X币什么的,很不爽,最后在GitHub上找到一个开源的,还有各种语言版本的,非常方便! https://github.co ...

  2. .NET MVC和.NET WEB api混用时注意事项

    1.同时配置了mvc路由和api路由时,mvc路由无法访问(调用所有mvc路由全部404错误) 在Global.asax中,需注意路由注册的顺序,将api路由注册放在最后: 即将 void Appli ...

  3. 【Python+OpenCV】人脸识别基于环境Windows+Python3 version_3(Anaconda3)+OpenCV3.4.3安装配置最新版安装配置教程

    注:本次安装因为我要安装的是win10(64bit)python3.7与OpenCV3.4.3教程(当下最新版,记录下时间2018-11-17),实际中这个教程的方法对于win10,32位又或是64位 ...

  4. CSP201709-1:打酱油

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  5. 数据库Mysql的学习(六)-子查询和多表操作

    )*0.05 WHERE card_id ='20121xxxxxx'; //子查询就是一个嵌套先计算子查询 SELECT * FROM borrow WHERE book_id =(SELECT b ...

  6. JDK源码分析:Integer.java部分源码解析

    1)声明部: public final class Integer extends Number implements Comparable<Integer> extends Number ...

  7. Python3 Tkinter-Radionbutton

    1.创建单选按钮 from tkinter import * root=Tk() Radiobutton(root,text='b1').pack() Radiobutton(root,text='b ...

  8. 20届的阿里 头条 网易 滴滴 百度 小米等Java面经

    转载连接 个人博客:junxuelian.cn 总结:个人感觉回答面试官问题不必太官方和书面化,腾讯sng招实习被发现照着百度百科念.结果可想而知.用自己的话和理解去回答就好.可能应届生会抱怨设计题, ...

  9. NFS服务搭建使用

    需求:由于线上业务有一些数据存在了Redis数据库和mysql数据库中了,导致了数据较大迁移起来比较麻烦,所以准备搭建NFS来做WEB的共享磁盘,存储这些数据. 服务端搭建: 查看本机关于nfs的包 ...

  10. Git使用笔记一(关于如何设置密钥及提交)(Windows)

    如何设置密钥 ssh-keygen -t rsa或ssh-keygen -t rsa -C ‘邮箱’ (注意 1.-t前有一个空格:2.keygen是key generate的缩写:3.而后连续输入三 ...