4698: Sdoi2008 Sandy的卡片

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 106  Solved: 40
[Submit][Status][Discuss]

Description

Sandy和Sue的热衷于收集干脆面中的卡片。然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型。每一张卡片都由一些数字进行标记,第i张卡片的序列长度为Mi,要想兑换人物模型,首先必须要集够N张卡片,对于这N张卡片,如果他们都有一个相同的子串长度为k,则可以兑换一个等级为k的人物模型。相同的定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串。Sandy的卡片数远远小于要求的N,于是Sue决定在Sandy的生日将自己的卡片送给Sandy,在Sue的帮助下,Sandy终于集够了N张卡片,但是,Sandy并不清楚他可以兑换到哪个等级的人物模型,现在,请你帮助Sandy和Sue,看看他们最高能够得到哪个等级的人物模型。

Input

第一行为一个数N,表示可以兑换人物模型最少需要的卡片数,即Sandy现在有的卡片数.
第i+1行到第i+N行每行第一个数为第i张卡片序列的长度Mi,之后j+1到j+1+Mi个数,用空格分隔,分别表示序列中.
的第j个数.
n<=1000,M<=1000,2<=Mi<=101

Output

一个数k,表示可以获得的最高等级。
 

Sample Input

2
2 1 2
3 4 5 9

Sample Output

2

HINT

Source

[Submit][Status][Discuss]

首先,对于题目中的匹配,可以转换成两个相邻数字之间差值的匹配问题。因此对于每个数字串,先前后做差得到新的数字串,然后把N个新串连起来求后缀数组。二分答案,在后缀数组中找出所有联系的height值>=k的区间,判断是否能满足存在N个在不同串中开始的后缀,如果能,就是一个合法的k。

调了好久都不对,满脸黑线,一怒之下打开Vim,参考hzwer的代码,没加tab就一A了。

 #include <bits/stdc++.h>
using namespace std;
#define N 1005
#define M 1000005
int n,mn=2e9,mx=,lt,rt=2e9,mid,ans=;
int a[N][N],l[N],b[M],id[M],tot,vis[N],cnt;
int sa[M],ta[M],rk[M],ht[M],wa[M],wb[M],ca[M],cb[M];
inline bool check(int k)
{
  for(int i=;i<=tot;++i)
  {
    if(ht[i]<k)memset(vis,,sizeof(vis)),cnt=;
    if(!vis[id[sa[i]]])vis[id[sa[i]]]=,++cnt;
    if(cnt==n)return true;
  }
  return false;
}
signed main(void)
{
  scanf("%d",&n);
  for(int i=;i<=n;++i)
  {
    scanf("%d",l+i);
    for(int j=;j<=l[i];++j)
    {
      scanf("%d",&a[i][j]);
      if(j>)mx=max(mx,a[i][j]-a[i][j-]);
    }
    rt=min(rt,l[i]);
  }
  for(int i=;i<=n;++i)
  {
    for(int j=;j<=l[i];++j)b[++tot]=a[i][j]-a[i][j-],id[tot]=i;
    b[++tot]=++mx;
  }
  for(int i=;i<=tot;++i)mn=min(mn,b[i]);
  for(int i=;i<=tot;++i)b[i]=b[i]-mn+,mx=max(mx,b[i]);
  memset(ca,,sizeof(ca));
  for(int i=;i<=tot;++i)++ca[b[i]];
  for(int i=;i<=mx;++i)ca[i]+=ca[i-];
  for(int i=tot;i>=;--i)sa[ca[b[i]]--]=i;
  rk[sa[]]=;
  for(int i=;i<=tot;++i)rk[sa[i]]=rk[sa[i-]]+(b[sa[i]]!=b[sa[i-]]);
  for(int k=;rk[sa[tot]]<tot;k<<=)
  {
    memset(ca,,sizeof(ca));
    memset(cb,,sizeof(cb));
    for(int i=;i<=tot;++i)++ca[wa[i]=rk[i]],++cb[wb[i]=i+k<=tot?rk[i+k]:];
    for(int i=;i<=tot;++i)ca[i]+=ca[i-],cb[i]+=cb[i-];
    for(int i=tot;i>=;--i)ta[cb[wb[i]]--]=i;
    for(int i=tot;i>=;--i)sa[ca[wa[ta[i]]]--]=ta[i];
    rk[sa[]]=;
    for(int i=;i<=tot;++i)rk[sa[i]]=rk[sa[i-]]+(wa[sa[i]]!=wa[sa[i-]]||wb[sa[i]]!=wb[sa[i-]]);
  }
  for(int i=,j=;i<=tot;++i)
  {
    if(--j<)j=;
    while(b[i+j]==b[sa[rk[i]-]+j])++j;
    ht[rk[i]]=j;
  }
  while(lt<=rt)
  {
    if(check(mid=(lt+rt)>>))
      ans=mid+,lt=mid+;
    else rt=mid-;
  }
  printf("%d\n",ans);
}

2017.01.13 补加Tab

@Author: YouSiki

BZOJ 4698: Sdoi2008 Sandy的卡片的更多相关文章

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

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

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

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

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

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

  4. ●BZOJ 4698 Sdoi2008 Sandy的卡片

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

  5. bzoj 4698: Sdoi2008 Sandy的卡片【SAM】

    差分之后用SAM求LCS,然后答案就是LCS+1 #include<iostream> #include<cstdio> #include<cstring> usi ...

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

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

  7. 4698. [SDOI2008]Sandy的卡片【后缀数组】

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

  8. 4698: Sdoi2008 Sandy的卡片

    前言 总之这个东西说起来很麻烦就是了, 思路 差分合并+后缀数组+二分(dddl) 类似于那个bzoj1031的复制子串和那个poj1743的差分 来看个例子 3 5 1 2 3 4 5 4 1 1 ...

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

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

随机推荐

  1. Lucene 时间排序

    在Lucene4.4中,想要实现搜索结果按照时间倒序的效果:如果两个文档得分相同,那么就按照发布时间倒序排列:否则就按照分数排列.这种效果在Lucene4.6中实现起来极其简单,直接利用search接 ...

  2. 一个语句创建Oracle所有表的序列

    -- 动态创建序列 declare cursor c_job is select TABLE_NAME from user_tables; c_row c_job%rowtype; v_sql ); ...

  3. Windows on Device 项目实践 3 - 火焰报警器制作

    在前两篇<Windows on Device 项目实践 1 - PWM调光灯制作>和<Windows on Device 项目实践 2 - 感光灯制作>中,我们学习了如何利用I ...

  4. Windows Phone App Studio发布重要更新-支持Windows 8.1 源代码生成

    自2013年8月Apps Team发布Windows Phone App Studio以来,由于其低入门门槛和较好的易用性,用户和项目数量增长迅速,从Windows Phone Developer B ...

  5. Linux的NTP配置总结

    在Linux系统中,为了避免主机时间因为在长时间运行下所导致的时间偏差,进行时间同步(synchronize)的工作是非常必要的.Linux系统下,一般使用ntp服务来同步不同机器的时间.NTP 是网 ...

  6. MYSQL服务器my.cnf配置文档详解

    MYSQL服务器my.cnf配置文档详解 硬件:内存16G [client] port = 3306 socket = /data/3306/mysql.sock [mysql] no-auto-re ...

  7. SQL闲杂知识点汇总【2015年12月】

    2015.12.14 知识点1:DEFAULT VALUES实现插入行 --临时创建临时表 CREATE TABLE [dbo].[tblTmp] ( iTmpID ,) NOT NULL PRIMA ...

  8. spark1.4.1 启动过程

    今天稍微没那么忙了,趁着这个时间,准备把spark的启动过程总结一下(),分享给大家.现在使用的spark1.4.1版本 当然前提是你已经把spark环境搭建好了. 1.我们启动spark的时候一般会 ...

  9. 数据分析:.Net程序员该如何选择?

    上文我介绍了用.Net实现的拉勾爬虫,可全站采集,其中.Net和C#(不区分)的数据爬取开始的早,全国主要城市都有一定数量的分布,加上有了近期其他相似技术类别的数据进行横向比较,可以得到比较合理的推测 ...

  10. Dialog详解(包括进度条、PopupWindow、自定义view、自定义样式的对话框)

    Dialog详解(包括进度条.PopupWindow.自定义view.自定义样式的对话框)   Android中提供了多种对话框,在实际应用中我们可能会需要修改这些已有的对话框.本实例就是从实际出发, ...