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 ...
随机推荐
- CSS分组和嵌套选择器
CSS 分组 和 嵌套 选择器 分组选择器 在样式表中有很多具有相同样式的元素.直线模组哪家好 h1 { color:green; } h2 { color:green; } p { ...
- linux基础知识-目录结构
linux的目录结构/bin:是Binary的缩写,这个目录存放着系统必备执行命令 /boot:这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文 件,自己的安装别放这里 /d ...
- Ubuntu下Arm-Linux-GCC交叉编译环境的搭建
1.下载arm-linux-gcc-3.4.1.tar.bz2到临时的目录下. 2.解压 arm-linux-gcc-3.4.1.tar.bz2 #tar -jxvf arm-linux-gcc-3. ...
- AcWing 227. 小部件厂 (高斯消元)打卡
题目:https://www.acwing.com/problem/content/description/229/ 题意:有很多个零件,每个零件的生产时间都在3-9天之间,现在只知道每个工人的生产部 ...
- LOAD CSV ERROR: The used command is not allowed with this MySQL version
要执行的sql 把csvload进db LOAD DATA LOCAL INFILE '/path/datas/temp.csv' INTO TABLE test_table_name FIELDS ...
- python 100day notes (1)
x1 + x2 +x3 + x4 = 8 多少正整数解 上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案 即用三个隔板插7个空位. 答案C(7,3) =35 # __name__是Pyt ...
- C++11中vector的几种遍历方法
假设有这样的一个vector: vector<int> line={1,2,3,4,5,6,7,8,9}; 需要输出vector里的每个元素,主函数如下: void showvec(con ...
- z-index只能用在定位元素上
弄了很久才突然想到z-index只能用在被定位的元素上. 定位的时候要注意给父级定位 在ie7里有问题的部分
- 【lua学习笔记】——在sublime中配置Lua运行环境
一.让Sublime可以运行lua脚本 打开sublime 选择tools-->Build System-->New Build System 在新出现的文件中输入如下内容: { &q ...
- mysql 安装运行学习过程中的报错问题
错误记录(windows端): 问题1:在启动MYSQL时出现问题:“ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' ...