题目描述

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

输入输出样例

输入样例#1: 复制

2
2 1 2
3 4 5 9

输出样例#1: 复制

2

说明

数据范围:

30%的数据保证n<=50

100%的数据保证n<=1000

因为是“相似”,所以把n个字符串差分

用不同且未出现的分隔符连起来

然后求后缀数组和LCP

二分答案k

把连续的h值不小于k的分为一组,如果一组内集齐了n个字符串的后缀

那么就可以构成长度为k的相似子串

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 int s[2000001],c[2000001],SA[2000001],h[2000001],n,m,x[2000001],y[2000001],rank[2000001],ans,tot,len[1501],cnt;
  8 int bel[2000001],mx=4000,a[2001][2001],top,st[2000001];
  9 bool vis[1501];
 10 void radix_sort()
 11 {int i;
 12   for (i=0;i<m;i++)
 13     c[i]=0;
 14   for (i=0;i<n;i++)
 15     c[x[y[i]]]++;
 16   for (i=1;i<m;i++)
 17     c[i]+=c[i-1];
 18   for (i=n-1;i>=0;i--)
 19     SA[--c[x[y[i]]]]=y[i];
 20 }
 21 void build_SA()
 22 {int i,j,k,p;
 23   for (i=0;i<n;i++)
 24     x[i]=s[i],y[i]=i;
 25   m=1000000;
 26   radix_sort();
 27   for (k=1;k<=n;k<<=1)
 28     {
 29       p=0;
 30       for (i=n-k;i<n;i++)
 31     y[p++]=i;
 32       for (i=0;i<n;i++)
 33     if (SA[i]>=k) y[p++]=SA[i]-k;
 34       radix_sort();
 35       p=1;swap(x,y);
 36       x[SA[0]]=0;
 37       for (i=1;i<n;i++)
 38     x[SA[i]]=((y[SA[i]]==y[SA[i-1]])&&((SA[i]+k<n?y[SA[i]+k]:-1)==(SA[i-1]+k<n?y[SA[i-1]+k]:-1)))?p-1:p++;
 39       if (p>=n) break;
 40       m=p;
 41     }
 42   for (i=0;i<n;i++)
 43     rank[SA[i]]=i;
 44   int L=0;
 45   for (i=0;i<n;i++)
 46     if (rank[i]>0)
 47       {
 48     if (L>0) L--;
 49     j=SA[rank[i]-1];
 50     while (i+L<n&&j+L<n&&(s[j+L]==s[i+L])) L++;
 51     h[rank[i]]=L;
 52       }
 53 }
 54 bool check(int mid)
 55 {
 56   int num=0;
 57   for(int i=0;i<=n;i++)
 58     {
 59       if(h[i]<mid)
 60     {
 61       num=0;
 62       while(top) vis[st[top--]]=0;
 63     }
 64       if(!vis[bel[SA[i]]])
 65     {
 66       vis[bel[SA[i]]]=1;
 67       num++;
 68       st[++top]=bel[SA[i]];
 69     }
 70       if(num==tot)return 1;
 71     }
 72   return 0;
 73 }
 74 int main()
 75 {int l,r,i,now,last,j;
 76   cin>>tot;r=2e9;
 77   for (i=1;i<=tot;i++)
 78     {
 79       scanf("%d",&len[i]);
 80       r=min(r,len[i]);
 81       for (j=1;j<=len[i];j++)
 82     {
 83       scanf("%d",&a[i][j]);
 84     }
 85     }
 86   for (i=1;i<=tot;i++)
 87     {
 88       for (j=2;j<=len[i];j++)
 89     {
 90       s[cnt]=a[i][j]-a[i][j-1]+2000;
 91       bel[cnt]=i;
 92       cnt++;
 93     }
 94       s[cnt++]=++mx;
 95     }
 96   n=cnt;
 97   build_SA();
 98   l=1;r--;
 99   ans=0;
100   while (l<=r)
101     {
102       int mid=(l+r)/2;
103       if (check(mid)) ans=mid,l=mid+1;
104       else r=mid-1;
105     }
106   cout<<ans+1;
107 }

转载于:https://www.cnblogs.com/Y-E-T-I/p/8480466.html

[SDOI2008]Sandy的卡片相关推荐

  1. 洛谷 P2463 [SDOI2008]Sandy的卡片 解题报告

    P2463 [SDOI2008]Sandy的卡片 题意 给\(n(\le 1000)\)串,定义两个串相等为"长度相同,且一个串每个数加某个数与另一个串完全相同",求所有串的最长公 ...

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

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

  3. 4698: Sdoi2008 Sandy的卡片

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

  4. BZOJ4698: Sdoi2008 Sandy的卡片

    题解: 裸后缀数组+二分答案 /**************************************************************Problem: 4698User: c20 ...

  5. [BZOJ4698][SDOI2008]Sandy的卡片(后缀自动机)

    差分之后就是求多串LCS. 对其中一个串建SAM,然后把其它串放在上面跑. 对SAM上的每个状态都用f[x]记录这个状态与当前串的最长匹配长度,res[x]是对每次的f[x]取最小值.答案就是res[ ...

  6. Luogu P2463 [SDOI2008]Sandy的卡片

    题目链接 \(Click\) \(Here\) 真的好麻烦啊..事实证明,理解是理解,一定要认认真真把板子打牢,不然调锅的时候真的会很痛苦..(最好是八分钟能无脑把\(SA\)码对的程度\(QAQ\) ...

  7. [luoguP2463] [SDOI2008]Sandy的卡片(后缀数组 + st表)

    传送门 很容易想到,题目中的相同是指差分数组相同. 那么可以把差分数组连起来,中间加上一个没有出现过的且字典序小的数 双指针移动,用st表维护height数组中的最小值. 当然用单调队列应该也可以且更 ...

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

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

  9. 洛咕 P2463 [SDOI2008]Sandy的卡片

    哈希水过. 首先这是一段delta相同的序列,按照套路差分一下,b[i]=a[i]-a[i-1],然后就是这些序列的最长公共子段 由于数据范围很小,就可以二分,枚举第一个序列的子段然后每个子序列暴力c ...

最新文章

  1. 网络数据被截取,该如何维权?
  2. 通过 OpenAPI 部署 Npcf_PolicyAuthorization-PostAppSessions API Service
  3. mac系统升级后使用gitxcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), miss
  4. Generic Polygon Module in MAME 0.120u1
  5. 2020-08-21 Qt+MSVC 强制中文UTF-8编码
  6. 用OpenStack构建中国人寿数据中心生产云
  7. 论文中baseline是什么意思?
  8. 2022爱分析·国央企数字化实践报告
  9. Python中列表的常用方法总结
  10. java中23%5_23.5 jumpserver介绍
  11. 21个数据科学家面试必须知道的问题和答案
  12. sap成本流怎么看_SAP计算产品成本的三种方法
  13. 怎么查看建筑图纸?有什么技巧吗?
  14. (转)Ogre 天龙八部 GridInfo文件格式说明(正确版)
  15. 使用OC实现单链表:创建、删除、插入、查询、遍历、反转、合并、判断相交、求成环入口...
  16. mysql的check约束怎么设置_MySQL怎么使用check约束
  17. 大学英语四级翻译技巧讲解
  18. AFNetwork 作用和用法详解
  19. 利用apache+wsgi运行你的django网站 - Open Idea - 博客大巴
  20. 手机移动端web总结

热门文章

  1. iBatis报java.lang.RuntimeException: Error setting property错误
  2. eclipse实现热部署和热启动
  3. Android开发:怎样把Android studio中的Library公布到Jcenter
  4. YYH的苍天大竹(NOIP模拟赛Round 6)
  5. Angular2响应式表单
  6. 2014Esri国际用户大会ArcGIS Online
  7. 上海巨人网络参与网络诈骗整个流程
  8. 曈曈妈妈设计的2010年台历模板
  9. asp.net使用mysql教程_在C#程序中使用MYSQL数据库
  10. linux进程--进程与线程(十二)