Sandy的卡片[SDOI2008]
题目传送门
题目描述
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,表示可以获得的最高等级。
输入输出样例
2 2 1 2 3 4 5 9
2
说明
数据范围:
30%的数据保证n<=50
100%的数据保证n<=1000,M<=1000,2<=Mi<=101
题解:
先对每个原串差分,再把n个差分后的串连在一起,中间用未出现过的字符隔开。求出height数组后进行二分答案,查看是否有满足条件的[l,r]使得区间内出现了n个卡组且height都大于等于二分出的x。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define LL long long 6 #define RI register int 7 using namespace std; 8 const int INF = 0x7ffffff ; 9 const int N = 1e6 + 1010 ; 10 11 inline int read() { 12 int k = 0 , f = 1 ; char c = getchar() ; 13 for( ; !isdigit(c) ; c = getchar()) 14 if(c == '-') f = -1 ; 15 for( ; isdigit(c) ; c = getchar()) 16 k = k*10 + c-'0' ; 17 return k*f ; 18 } 19 int n, nn, k, p, q = 1, tot = 0, res = 0 ; int a[N], bl[N], sa[2][N], rk[2][N], h[N], v[N] ; 20 21 inline void mul(int *sa,int *rk,int *SA,int *RK) { 22 for(int i=1;i<=n;i++) v[rk[sa[i]]] = i ; 23 for(int i=n;i;i--) if(sa[i] > k) SA[v[rk[sa[i]-k]]--] = sa[i]-k ; 24 for(int i=n-k+1;i<=n;i++) SA[v[rk[i]]--] = i ; 25 for(int i=1;i<=n;i++) RK[SA[i]] = RK[SA[i-1]] + (rk[SA[i]] != rk[SA[i-1]] || rk[SA[i]+k] != rk[SA[i-1]+k]) ; 26 } 27 inline void presa() { 28 for(int i=1;i<=n;i++) v[a[i]]++ ; 29 for(int i=1;i<=222;i++) v[i] += v[i-1] ; 30 for(int i=1;i<=n;i++) sa[p][v[a[i]]--] = i ; 31 for(int i=1;i<=n;i++) rk[p][sa[p][i]] = rk[p][sa[p][i-1]] + (a[sa[p][i]] != a[sa[p][i-1]]) ; 32 for(k=1;k<n;k<<=1,swap(p,q)) { 33 mul(sa[p],rk[p],sa[q],rk[q]) ; 34 if(rk[q][sa[q][n]] == n) { 35 swap(p,q) ; break ; 36 } 37 } 38 for(int i=1,k=0;i<=n;i++) { 39 int j = sa[p][rk[p][i]-1] ; 40 while(a[i+k] == a[j+k]) k++ ; 41 h[rk[p][i]] = k ; if(k) k-- ; 42 } 43 } 44 45 int vv[1010] ; 46 inline void add(int x) { 47 if(!x) return ; 48 if(!vv[x]) res ++ ; 49 vv[x]++ ; 50 } 51 inline void del(int x) { 52 if(!x) return ; 53 vv[x]-- ; 54 if(!vv[x]) res -- ; 55 } 56 inline bool check(int x) { 57 memset(vv,0,sizeof(vv)) ; 58 int pre = 0 ; res = 0 ; 59 for(int i=1;i<=n;i++) { 60 if(h[i] < x) { 61 if(res == nn) return 1 ; 62 for(int j=pre+1;j<i;j++) del(bl[sa[p][j]]), del(bl[sa[p][j-1]]) ; 63 pre = i ; 64 } 65 else add(bl[sa[p][i]]), add(bl[sa[p][i-1]]) ; 66 } 67 if(res == nn) return 1 ; // 刚刚那个提交少了这一行,其实是有漏洞的qaq 68 return 0 ; 69 } 70 71 int main() { 72 n = read() ; 73 for(int i=1;i<=n;i++) { 74 int mm = read() ; int now, pre = read() ; 75 for(int j=1;j<mm;j++) now = read(), a[++tot] = now-pre+102, pre = now, bl[tot] = i ; 76 if(i < n) a[++tot] = 222 ; 77 } 78 nn = n ; n = tot ; presa() ; 79 int L = 0, R = n, ans = 0 ; 80 while(L < R) { 81 int mid = (L+R)>>1 ; 82 if(check(mid)) ans = max(ans,mid), L = mid+1 ; 83 else R = mid ; 84 } 85 /* 86 for(int i=1;i<=n;i++) printf("%d ",a[i]) ; printf("\n") ; 87 for(int i=1;i<=n;i++) printf("%d ",h[rk[p][i]]) ; printf("\n") ; 88 */ 89 printf("%d",ans+1) ; 90 return 0 ; 91 }
又一次把v[]开小了...不会再有下一次了qaq
转载于:https://www.cnblogs.com/zub23333/p/8760882.html
Sandy的卡片[SDOI2008]相关推荐
- 洛谷 P2463 [SDOI2008]Sandy的卡片 解题报告
P2463 [SDOI2008]Sandy的卡片 题意 给\(n(\le 1000)\)串,定义两个串相等为"长度相同,且一个串每个数加某个数与另一个串完全相同",求所有串的最长公 ...
- 【bzoj4698】[Sdoi2008] Sandy的卡片 后缀数组
题目描述 Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型.每一张卡片都由一些数字进行标记,第i张卡片的序列 ...
- [SDOI2008]Sandy的卡片
题目描述 Sandy和Sue的热衷于收集干脆面中的卡片. 然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型. 每一张卡片都由一些数字进行标记,第i张卡片的 ...
- 【SDOI2008】Sandy的卡片(后缀数组)
题目描述 Sandy和Sue的热衷于收集干脆面中的卡片. 然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型. 每一张卡片都由一些数字进行标记,第i张卡片的 ...
- 洛谷P2463 Sandy的卡片【后缀数组】【二分】
题目描述 Sandy和Sue的热衷于收集干脆面中的卡片. 然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型. 每一张卡片都由一些数字进行标记,第i张卡片的 ...
- 4698: Sdoi2008 Sandy的卡片
前言 总之这个东西说起来很麻烦就是了, 思路 差分合并+后缀数组+二分(dddl) 类似于那个bzoj1031的复制子串和那个poj1743的差分 来看个例子 3 5 1 2 3 4 5 4 1 1 ...
- BZOJ4698: Sdoi2008 Sandy的卡片
题解: 裸后缀数组+二分答案 /**************************************************************Problem: 4698User: c20 ...
- [BZOJ4698][SDOI2008]Sandy的卡片(后缀自动机)
差分之后就是求多串LCS. 对其中一个串建SAM,然后把其它串放在上面跑. 对SAM上的每个状态都用f[x]记录这个状态与当前串的最长匹配长度,res[x]是对每次的f[x]取最小值.答案就是res[ ...
- Luogu P2463 [SDOI2008]Sandy的卡片
题目链接 \(Click\) \(Here\) 真的好麻烦啊..事实证明,理解是理解,一定要认认真真把板子打牢,不然调锅的时候真的会很痛苦..(最好是八分钟能无脑把\(SA\)码对的程度\(QAQ\) ...
- [luoguP2463] [SDOI2008]Sandy的卡片(后缀数组 + st表)
传送门 很容易想到,题目中的相同是指差分数组相同. 那么可以把差分数组连起来,中间加上一个没有出现过的且字典序小的数 双指针移动,用st表维护height数组中的最小值. 当然用单调队列应该也可以且更 ...
最新文章
- K-近邻算法之案例:鸢尾花种类预测—流程实现
- 最详细的JavaWeb开发基础之java环境搭建(Windows版)
- oracle 11g 大小,修改oracle 11GR2归档模式和归档目录及大小-Oracle
- 005_JDK的Date类对Comparable接口的实现
- [python] 常用正则表达式爬取网页信息及分析HTML标签总结
- 《Python编程从入门到实践》学习笔记8(第9章:类)
- cocos2dx--cocos2dx3.1.1执行报无法解析的外部符号
- SubSonic中的字段付值--MakeOld Update
- s2 安恒 漏洞验证工具_Struts2漏洞利用工具下载(更新2017-V1.8版增加S2-045/S2-046)-阿里云开发者社区...
- java -- 对Map按键排序、按值排序
- ias日志察看器(.net)
- etcd 及 etcd 在 k8s中的用法
- Android 仿微信/支付宝 字体大小 调整控件
- WSAData结构体的作用
- Low-shot Visual Recognition by Shrinking and Hallucinating Features
- 设计一个电商平台积分兑换系统
- 2008年度中国最佳MBA排行榜
- IOS 开发必备网址
- html怎样给名片加边框,添加边框和底纹
- 【C++实训】基于MVC模型开发的高校教务管理系统【附完整报告+示例程序+日记+源码】