BZOJ 4698: Sdoi2008 Sandy的卡片(后缀数组+差分+二分答案)
解题思路
看到一个子串加一个数字到另一个子串,自然可以想到差分。然后要把所有串都拼起来,求出\(height\)数组后可以二分答案来做,每次二分一个答案后统计一下连续的\(height>=\)二分出答案的段是否将每个串都涵盖。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN = 210005;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f?x:-x;
}
inline int min(int x,int y){
return x<y?x:y;
}
inline int max(int x,int y){
return x>y?x:y;
}
int n,Mi[1005],ans,num,tot,m,cnt,stk[MAXN],top;
int sa[MAXN],x[MAXN<<1],y[MAXN<<1],c[MAXN],vis[MAXN];
int rk[MAXN],height[MAXN],a[MAXN];
bool ok[MAXN];
void get_SA(){
for(int i=1;i<=tot;i++) x[i]=a[i],c[x[i]]++;
for(int i=2;i<=m;i++) c[i]+=c[i-1];
for(int i=tot;i;i--) sa[c[x[i]]--]=i;
for(int k=1;k<=tot;k<<=1){num=0;
for(int i=tot-k+1;i<=tot;i++) y[++num]=i;
for(int i=1;i<=tot;i++) if(sa[i]>k) y[++num]=sa[i]-k;
memset(c,0,sizeof(c));
for(int i=1;i<=tot;i++) c[x[i]]++;
for(int i=2;i<=m;i++) c[i]+=c[i-1];
for(int i=tot;i;i--) sa[c[x[y[i]]]--]=y[i],y[i]=0;
swap(x,y);num=1;x[sa[1]]=1;
for(int i=2;i<=tot;i++)
x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
m=num;if(m==tot) break;
}
}
void get_height(){
for(int i=1;i<=tot;i++) rk[sa[i]]=i;int k=0,j;
for(int i=1;i<=tot;i++){
if(rk[i]==1) continue;
if(k) k--;j=sa[rk[i]-1];
while(i+k<=tot && j+k<=tot && a[i+k]==a[j+k]) k++;
height[rk[i]]=k;
}
}
inline bool check(int lim){
while(top) ok[stk[top--]]=0;cnt=0;
for(int i=1;i<=tot;i++){
if(height[i]<lim) {while(top) ok[stk[top--]]=0;cnt=0;}
if(!ok[vis[sa[i]]]) stk[++top]=vis[sa[i]],ok[vis[sa[i]]]=1,cnt++;
if(cnt==n) return true;
}
return false;
}
int main(){
n=rd();int pre,zz;
for(int i=1;i<=n;i++){
Mi[i]=rd();pre=0;a[++tot]=i+50000;
for(int j=1;j<=Mi[i];j++) zz=rd(),a[++tot]=zz-pre+3000,pre=zz,vis[tot]=i;
}
for(int i=1;i<=tot;i++) m=max(m,a[i]);
get_SA();get_height();int l=0,r=102,mid;
while(l<=r){
mid=(l+r)>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans+1);
return 0;
}
BZOJ 4698: Sdoi2008 Sandy的卡片(后缀数组+差分+二分答案)的更多相关文章
- BZOJ 4698: Sdoi2008 Sandy的卡片 后缀数组 + RMQ + 查分
题目描述 Sandy和Sue的热衷于收集干脆面中的卡片. 然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型. 每一张卡片都由一些数字进行标记,第i张卡片的 ...
- BZOJ 4698: Sdoi2008 Sandy的卡片 [后缀自动机]
4698: Sdoi2008 Sandy的卡片 题意:差分后就是多个串LCS SAM+map大法好 模板打错 智力-2 #include <iostream> #include <c ...
- BZOJ 4698: Sdoi2008 Sandy的卡片
4698: Sdoi2008 Sandy的卡片 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 106 Solved: 40[Submit][Stat ...
- SDOI2008 Sandy的卡片( 后缀数组 )
求出后缀数组, 然后二分答案, 对height数组分组检验答案. 时间复杂度O(|S| log|S|) ------------------------------------------------ ...
- 【BZOJ4698】Sdoi2008 Sandy的卡片 后缀数组+RMQ
[BZOJ4698]Sdoi2008 Sandy的卡片 Description Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡 ...
- ●BZOJ 4698 Sdoi2008 Sandy的卡片
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4698 题解: 后缀数组,二分这个题还是比较套路的.首先依据题意,把各个串差分以后,用分割符号 ...
- 【bzoj4698】[Sdoi2008] Sandy的卡片 后缀数组
题目描述 Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型.每一张卡片都由一些数字进行标记,第i张卡片的序列 ...
- 【刷题】BZOJ 4698 Sdoi2008 Sandy的卡片
Description Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型.每一张卡片都由一些数字进行标记,第 ...
- BZOJ4698: Sdoi2008 Sandy的卡片(后缀数组 二分)
题意 题目链接 Sol 不要问我为什么发两篇blog,就是为了骗访问量 后缀数组的也比较好想,先把所有位置差分,然后在height数组中二分就行了 数据好水啊 // luogu-judger-enab ...
随机推荐
- 每天一个linux命令:mv(7)
mv mv命令可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 在跨文件系统移动文件时,mv先拷贝,再将原有文件删除, ...
- Hibernate学习 (一)
Hibernate错误总结: 1:不能自动创建表.把MySQL的版本的方言修改一下. 首先自己要注意自己的MYSQL版本,然后设置对应的方言 兼容性模式 <property name=" ...
- 洛谷P2786 英语1(eng1)- 英语作文
题目背景 蒟蒻HansBug在英语考场上,挠了无数次的头,可脑子里还是一片空白. 题目描述 眼下出现在HansBug蒟蒻面前的是一篇英语作文,然而智商捉急的HansBug已经草草写完了,此时 他发现离 ...
- 概念介绍:IaaS、PaaS、SaaS
云计算分几层的,分别是Infrastructure(基础设施)-as-a-Service,Platform(平台)-as-a-Service,Sofware(软件)-as -a -Service.基础 ...
- HTML5: HTML5 测验
ylbtech-HTML5: HTML5 测验 1.返回顶部 1. HTML5 测验 结果:15/5 1. HTML5 之前的 HTML 版本是什么? 你的回答: HTML 4.01 回答正确! 2. ...
- 数据访问层的超级基类AbstractBaseDAL
using System; using System.Collections; using System.Data; using System.Data.Common; using System.Co ...
- 高水线 High water mark(HWM)
所有的Oracle表都有一个容纳数据的上限(很像一个水库历史最高的水位),我们把这个上限称为“High water mark"或HWM.这个HWM是一个标记(专门有一个数据块来记录高水标记等 ...
- EmWin 如何显示汉字 不用在文件中使用编码
1. Font Converter for emWin 生成C文件字库 1.1 新建文件 1.2 选择字体 1.3 为了减小C文件体积,这里只加入自己需要的汉字,先把所有字体取消选择. 1.4 新建一 ...
- AVL树,C语言实现,完整代码,先贴上,讲解稍后
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #de ...
- hql例子
/** * 根据搜索条件查询商品(带缓存) */ public List<ResultInfo> getSearchGoodsList(GoodsTypeCondtionBizBean c ...