题目描述

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,表示可以获得的最高等级

题解:

所有字符都可以加上一个数.......
好像不太好搞.......
差分一下就好了.......
差分一下,求 $height[]$ 数组,在所有排完序的后缀上弄左右两个指针扫描.
随着左指针右移,右指针也必须右移.
每次碰到一个新的串就 $++cnt$, $cnt=n$ 就可以用 $RMQ$ 查一下结果并更新答案.

Code:

#include <bits/stdc++.h>
#define setIO(s) freopen(s".in", "r" , stdin)
#define maxn 500000
#define N 2000
#define inf 10000
using namespace std;
int n,m;
int arr[maxn], num[maxn], A[maxn], tag[maxn], cnt[maxn];
namespace SA
{
int rk[maxn], tp[maxn], tax[maxn], sa[maxn], height[maxn], Log[maxn], dp[maxn][23];
void qsort()
{
for(int i=0;i<=m;++i) tax[i]=0;
for(int i=1;i<=n;++i) ++tax[rk[i]];
for(int i=1;i<=m;++i) tax[i]+=tax[i-1];
for(int i=n;i>=1;--i) sa[tax[rk[tp[i]]]--]=tp[i];
}
void construct()
{
for(int i=1;i<=n;++i) rk[i]=arr[i],tp[i]=i;
qsort();
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(int i=n-k+1;i<=n;++i) tp[++p]=i;
for(int i=1;i<=n;++i) if(sa[i]>k) tp[++p]=sa[i]-k;
qsort(), swap(tp,rk), rk[sa[1]]=p=1;
for(int i=2;i<=n;++i)
rk[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+k]==tp[sa[i]+k])?p:++p;
if(p==n) break;
m=p;
}
int k=0;
for(int i=1;i<=n;++i)rk[sa[i]]=i;
for(int i=1;i<=n;++i)
{
if(k)--k;
int j=sa[rk[i]-1];
while(arr[i+k]==arr[j+k])++k;
height[rk[i]]=k;
}
}
void RMQ()
{
for(int i=2;i<=n;++i) Log[i]=Log[i>>1]+1;
for(int i=1;i<=n;++i) dp[i][0]=height[i];
for(int j=1;(1<<j)<=n;++j)
for(int i=1;i+(1<<j)-1<=n;++i)
dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
}
int getmin(int a,int b)
{
int k=Log[b-a+1];
return min(dp[a][k],dp[b-(1<<k)+1][k]);
}
};
int main()
{
// setIO("input");
int tot;
scanf("%d",&tot);
for(int i=1,o,h;i<=tot;++i)
{
scanf("%d",&o);
for(int j=1;j<=o;++j) scanf("%d",&A[j]);
for(int j=2;j<=o;++j) arr[++n]=(A[j]-A[j-1]+inf),tag[n]=i;
arr[++n]=(inf<<1)+i;
}
m=(inf<<1)+(tot<<1), SA::construct(), SA::RMQ();
int ty=0,l=1,ans=0;
for(int i=1;i<=n;++i)
{
int o=SA::sa[i];
if(!tag[o]) continue;
if(!cnt[tag[o]]) ++ty;
++cnt[tag[o]];
for(;l<i;++l)
{
if(!tag[SA::sa[l]]) continue;
if(cnt[tag[SA::sa[l]]] > 1)
--cnt[tag[SA::sa[l]]];
else
break;
}
if(ty==tot)
{
ans=max(ans,SA::getmin(l+1,i) + 1);
}
}
printf("%d\n",ans);
return 0;
}

  

BZOJ 4698: Sdoi2008 Sandy的卡片 后缀数组 + RMQ + 查分的更多相关文章

  1. BZOJ 4698: Sdoi2008 Sandy的卡片(后缀数组+差分+二分答案)

    传送门 解题思路 看到一个子串加一个数字到另一个子串,自然可以想到差分.然后要把所有串都拼起来,求出\(height\)数组后可以二分答案来做,每次二分一个答案后统计一下连续的\(height> ...

  2. BZOJ 4698: Sdoi2008 Sandy的卡片 [后缀自动机]

    4698: Sdoi2008 Sandy的卡片 题意:差分后就是多个串LCS SAM+map大法好 模板打错 智力-2 #include <iostream> #include <c ...

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

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

  4. BZOJ 4698: Sdoi2008 Sandy的卡片

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

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

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

  6. 【刷题】BZOJ 4698 Sdoi2008 Sandy的卡片

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

  7. ●BZOJ 4698 Sdoi2008 Sandy的卡片

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4698 题解: 后缀数组,二分这个题还是比较套路的.首先依据题意,把各个串差分以后,用分割符号 ...

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

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

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

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

随机推荐

  1. Office 2003的卸载 与 Office 2013 的安装

    一.Office 2003的卸载 软件:卸载Office2003.msi 运行该软件,等待几分钟即可, 二.Office 2013 的安装 1.Office Professional Plus 201 ...

  2. 详解Pattern类和Matcher类

    java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现(建议在阅读本文时,打开java API文档,当介绍到哪个方法时,查看java API中的方法说明,效果 ...

  3. P1294 高手去散步 洛谷

    https://www.luogu.org/problem/show?pid=1294#sub 题目背景 高手最近谈恋爱了.不过是单相思.“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求.今天 ...

  4. 飘逸的python - 实现glob style pattern

    一说起通配符,大家非常快就会想起*和? 号,有了通配符,使得表达能力大大增强,非常多linux命令都支持这个东西,事实上就是glob style pattern. 就连redis的keys命令都支持g ...

  5. Facebook图搜索unicorn

    unicorn(独角兽),里面类似于倒排链的reference list,相应的term如friend:2,表示entity 2的朋友列表,整个结构是shard的,上面是top aggregator, ...

  6. centos改动sshport

    vi /etc/ssh/sshd_config 找到#Port 22一段,这里是标识默认使用22port.加入一行例如以下: Port 34981 然后保存退出 然后service sshd rest ...

  7. Codeboy Blog的搭建

    本文介绍了codeboy.me站点的搭建过程. 站点使用了jeykll进行构建.在CleanBlog等模板的基础上进行改造. jekyll是一个简单的免费的Blog生成工具,类似WordPress.可 ...

  8. 操作系统: 二级文件夹文件系统的实现(c/c++语言)

    操作系统的一个课程设计,实现一个二级文件夹文件系统. 用disk.txt模拟磁盘,使用Help查看支持的命令及其操作方式,root为超级用户(写在disk.txt中) 文件的逻辑结构:流式文件. 物理 ...

  9. 1D1D动态规划优化

    1D1D动态规划优化 1D/1D 动态规划优化初步所谓1D/1D 动态规划,指的是状态数为O(n),每一个状态决策量为O(n)的动态规划方程.直接求解的时间复杂度为O(n2),但是,绝大多数这样的方程 ...

  10. 洛谷 P3515 [ POI 2011 ] Lightning Conductor —— 决策单调性DP

    题目:https://www.luogu.org/problemnew/show/P3515 决策单调性... 参考TJ:https://www.cnblogs.com/CQzhangyu/p/725 ...