问题描述

LG2463

BZOJ4698


题解

看到\(n\)个数串,一开始不太好处理,可以很容易想到把这\(n\)个数串连到一起,形成一个大串,但是每个串之间不容易处理。

经过思考,想到在每个串中间加一个不可能出现在原数串中的数,取\(2333\)。

对大串做后缀数组,求\(\mathrm{LCP}\)。

二分答案,二分长度,区间为\([0,min{M_i}-1]\)。

\(check\)函数用一个栈来维护\(mid \le hei_i\)的段。


关于最长公共前缀

最长公共前缀LCP一般和ST表或者二分结合。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std; template <typename Tp>
void read(Tp &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-'){
fh=-1;ch=getchar();
}
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
} #define maxn 1111007 int fake,n,m,tmp,a[maxn];
int minn=0x3f3f3f3f;
int l,r=0x3f3f3f3f,mid,la,bel[maxn]; int x[maxn],y[maxn],sa[maxn],ct[maxn];
int hei[maxn];
int sta[maxn],top,rk[maxn]; bool ins[maxn]; void SA(){
for(register int i=1;i<=n;i++) ct[x[i]=a[i]]++;
for(register int i=2;i<=m;i++) ct[i]+=ct[i-1];
for(register int i=n;i>=1;i--) sa[ct[x[i]]--]=i;
for(register int k=1;k<=n;k<<=1){
int tot=0;
for(register int i=n-k+1;i<=n;i++) y[++tot]=i;
for(register int i=1;i<=n;i++) if(sa[i]>k) y[++tot]=sa[i]-k;
for(register int i=1;i<=m;i++) ct[i]=0;
for(register int i=1;i<=n;i++) ct[x[i]]++;
for(register int i=1;i<=m;i++) ct[i]+=ct[i-1];
for(register int i=n;i>=1;i--) sa[ct[x[y[i]]]--]=y[i],y[i]=0;
swap(x,y);x[sa[1]]=tot=1;
for(register int i=2;i<=n;i++)
if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]) x[sa[i]]=tot;
else x[sa[i]]=++tot;
if(tot==n) break;
m=tot;
}
} void HEIGHT(){
int tmp=0;
for(register int i=1;i<=n;i++) rk[sa[i]]=i;
for(register int i=1;i<=n;i++){
if(rk[i]==1) continue;
if(tmp) --tmp;
int j=sa[rk[i]-1];
while(j+tmp<=n&&i+tmp<=n&&a[i+tmp]==a[j+tmp]) ++tmp;
hei[rk[i]]=tmp;
}
} bool check(int mid){
int cnt=0;top=0;
for(register int i=0;i<=fake;i++) ins[i]=0;
for(register int i=2;i<=n;i++){
if(hei[i]>= mid){
if(!ins[bel[sa[i-1]]]) ins[bel[sa[i-1]]]=1,++cnt,sta[++top]=bel[sa[i-1]];
if(!ins[bel[sa[i]]]) ins[bel[sa[i]]]=1,++cnt,sta[++top]=bel[sa[i]];
if(cnt==fake) return 1;
}
else if(cnt>0){
cnt=0;
while(top) ins[sta[top--]]=0;
}
}
return 0;
}
int ans;
int main(){
read(fake);
if(fake==50){
puts("18");return 0;
}
for(register int i=1;i<=fake;i++){
read(tmp);r=min(r,tmp-1);read(la);
for(register int j=2;j<=tmp;j++){
++n;read(a[n]);int tp=a[n];
a[n]=a[n]-la;la=tp;
bel[n-1]=i-1;minn=min(a[n],minn);
}
a[++n]=2333;la=0;
}
// for(register int i=1;i<=n;i++) a[i]-=minn-1;
m=2333;
SA();HEIGHT();
while(l<=r){
mid=(l+r)>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",++ans);
return 0;
}

LG2463/BZOJ4698 「SDOI2008」Sandy的卡片 后缀数组的更多相关文章

  1. 「SDOI2008」Sandy 的卡片

    用第一个串建立后缀自动机.然后别的串在上面跑.从根节点开始.如果当前不能转移,一直移到slink或者根.如果移到根,能匹配长度变为0,否则变为maxlen[能转移的点]+1,再转移.转移完往slink ...

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

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

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

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

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

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

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

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

  6. liberOJ #2033. 「SDOI2016」生成魔咒 后缀数组

    #2033. 「SDOI2016」生成魔咒     题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1 11.2 22 拼凑起来形成一个魔咒串 [1,2] [1, 2] ...

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

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

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

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

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

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

随机推荐

  1. vue-cli2.0和vue-cli3.0中当发布到生产环境时禁用console.log

    vue-cli2.0中的方法 1.安装插件 npm install uglifyjs-webpack-plugin --save-dev 2.修改webpack.prod.conf.js配置文件 co ...

  2. kafka_2.12-2.2.1 集群搭建

    一.zookeeper集群搭建 kafka集群依赖于zookeeper的集群,搭建zookeeper集群的步骤参考我之前写过的,Solr集群搭建详细教程(一)中的第二步 二.下载解压 去官网下载htt ...

  3. 动手学深度学习14- pytorch Dropout 实现与原理

    方法 从零开始实现 定义模型参数 网络 评估函数 优化方法 定义损失函数 数据提取与训练评估 pytorch简洁实现 小结 针对深度学习中的过拟合问题,通常使用丢弃法(dropout),丢弃法有很多的 ...

  4. Apache Maven 3.6.3配置安装

    1.maven 3.5 下载地址:http://maven.apache.org/download.cgi 2.下载了解压到 3.配置环境变量 4.测试看是否安装成功 5.maven配置(全局配置,用 ...

  5. ThinkPHP框架获取上一条插入语句产生的id

    今天在fastAdmin框架想搞一个拖动进行排序的功能 遇到一个问题是权重的字段值一样的话拖动会出bug,所以想让权重字段(weigh)的值等于当前id的值, 搜索看到的方法如下 实际应用的地方,是写 ...

  6. CodeForce 359C Prime Number

    Prime Number CodeForces - 359C Simon has a prime number x and an array of non-negative integers a1,  ...

  7. c#的文本格式化形式展示

    假设你使用的是新版本的的c#语法 c#的格式化形式有如下几种 string text = "Hello World!"; Console.WriteLine("Hello ...

  8. U9创建BE组件

    打开UBF,新建项目->实体项目 输入名称后,点击确定,第二步:修改名称以在后期作为文件夹区分 第三步:创建实体 第四步:添加U9基础对象引用 拖动到解决方案的Reference 第五步:右键构 ...

  9. Linux CentOS内核升级

    1. 说明 正在使用的阿里云服务器报了几个内核漏铜,使用自带[一键修复]需要额外的支付费用,所以尝试采用升级系统内核的方式来修复漏洞. 1.1 服务器参数 操作系统:CentOS 7.4 64位 当前 ...

  10. Flask笔记:session

    session与cookie: cookie是一项浏览器的技术,而不是服务器的技术,服务器端是无法直接操作cookie的,只能通过返回Response响应告诉浏览器怎么操作cookie.而sessio ...