传送门

题目:

Description

小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。 小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。

Input

第一行包含两个整数N, K,分别表示彩珠的总数以及种类数。接下来K行,每行第一个数为Ti,表示第i种彩珠的数目。接下来按升序给出Ti个非负整数,为这Ti个彩珠分别出现的位置。

Output

应包含一行,为最短彩带长度。

Sample Input

6 3
1 5
2 1 7
3 1 3 8

Sample Output

3

HINT

有多种方案可选,其中比较短的是1~5和5~8。后者长度为3最短。
【数据规模】
对于50%的数据, N≤10000;
对于80%的数据, N≤800000;
对于100%的数据,1≤N≤1000000,1≤K≤60,0≤彩珠位置<2^31。

题解:

写法大意:单调队列

sort一遍保证位置的单调性,开一个pos数组存第i种彩带最后出现的位置,出队的时候判断一下那个元素的位置是否与pos数组相同即可(不同才能出队)

就样例来模拟一波:

6 3
1 5
2 1 7
3 1 3 8

进行排序以后的f数组:

f[i].x 2 3 3 1 2 3
f[i].y 1 1 3 5 7 8

(pos数组要先初始化为-1)

(len要初始化为f[n].y-f[1].y,即最坏的情况(否则会有5个点挂掉(luogu会,bzoj没试过)))

当i=1时

pos[f[i].x]为-1,那么f[i]入队,队列中的珠子多了一个了,cnt++

更新pos[f[i].x]的值为f[i].y

开始出队操作:

当队头head<=队尾i且队头的元素所在位置f[head].y!=该位置珠子最后出现的位置(即pos[f[head].x])时就可以出队了!

最后更新一下答案:

当cnt(队列内珠子种数)=k(珠子种数)时就可以更新答案了!

len=min(len,f[i].y-f[head].y)

这样从头枚举到尾就好了,时间复杂度(nlogn)(排序需要nlogn的时间复杂度)

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll int
#define min(x,y) x<y?x:y
inline void read(ll &x){
x=;ll f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-f;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
x*=f;
}
using namespace std;
#define N 1000010
struct node{ll x,y;}f[N];
//x表示所属彩珠类型,y表示w位置
ll n,k,len,pos[N];
bool cmp(node x,node y){return x.y<y.y;}
int main(){
read(n);read(k);ll a,b=;
for(ll i=;i<=k;i++){
read(a);pos[i]+=a;
for(ll j=;j<=a;j++){
read(f[++b].y);
f[b].x=i;
}
}
sort(f+,f+n+,cmp);
len=f[n].y-f[].y;ll head=,cnt=;
memset(pos,-,sizeof(pos));
for(ll i=;i<=n;i++){
if(pos[f[i].x]==-)cnt++;
pos[f[i].x]=f[i].y;
while(head<=i&&f[head].y!=pos[f[head].x])head++;
if(cnt==k&&f[i].y-f[head].y<len)len=f[i].y-f[head].y;
}
printf("%d",len);
return ;
}

再提供一个本质上没有区别但是长得比较好看的代码(我以前码风好丑啊

#include <bits/stdc++.h>

using namespace std ;

#define N 1000010

int n , k ;
int last[ N ] ;
struct node {
int id , x ;
}a[ N ] ; bool cmp( node a , node b ) {
return a.x < b.x ;
} int main() {
scanf( "%d%d" , &n , &k ) ;
int tot = ;
for( int i = ; i <= k ; i ++ ) {
int t ;
scanf( "%d" , &t ) ;
for( int j = ; j <= t ; j ++ ) {
scanf( "%d" , &a[ ++ tot ].x ) ;
a[ tot ].id = i ;
}
}
sort( a + , a + n + , cmp ) ;
int l = , ans = a[ n ].x - a[ ].x , cnt = ;
for( int i = ; i <= n ; i ++ ) {
if( !last[ a[ i ].id ] ) cnt ++ ;
last[ a[ i ].id ] = a[ i ].x ;
while( last[ a[ l ].id ] != a[ l ].x && l <= i ) l ++ ;
if( cnt == k && a[ i ].x - a[ l ].x < ans ) ans = a[ i ].x - a[ l ].x ;
}
printf( "%d\n" , ans ) ;
return ;
}

转载请注明出处哈:http://www.cnblogs.com/henry-1202/p/8666497.html

[bzoj 1293] [SCOI2009] 生日礼物的更多相关文章

  1. BZOJ 1293: [SCOI2009]生日礼物【单调队列】

    1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2534  Solved: 1383[Submit][Stat ...

  2. BZOJ 1293 SCOI2009 生日礼物 堆

    题目大意:给定一个数轴上n个点,每一个点有一种颜色,一共k种颜色.求一个最短的区间,包括全部k种颜色 卡了一段时间0.0 一開始想二分答案啥的 后来发现数据范围太大写不了0.0 后来去找题解才发现尼玛 ...

  3. bzoj 1293: [SCOI2009]生日礼物 问题转化 + 性质分析 + 滚动数组优化

    Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩 ...

  4. 1293: [SCOI2009]生日礼物

    1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1096  Solved: 584[Submit][Statu ...

  5. 1293: [SCOI2009]生日礼物 - BZOJ

    Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩 ...

  6. bzoj1293[SCOI2009]生日礼物 尺取法

    1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2838  Solved: 1547[Submit][Stat ...

  7. bzoj1293: [SCOI2009]生日礼物(stl堆)

    1293: [SCOI2009]生日礼物 题目:传送门 题解: 据说这道题乱搞随便就水过了 本蒟蒻想到了一个用堆的水法(还专门学了学queue): 如果把每一种颜色的下一个位置都记录一下的话,一开始就 ...

  8. [BZOJ 1293] 生日礼物

    Link: BZOJ 1293 传送门 Solution: 这题直接上尺取法就行了吧 先将每种颜色第一个放入优先队列,用$mx$维护当前的末尾位置 每次取出第一个颜色,更新答案.将其下一个放入队列中去 ...

  9. 【BZOJ1293】[SCOI2009]生日礼物(单调队列)

    [BZOJ1293][SCOI2009]生日礼物(单调队列) 题面 BZOJ 洛谷 题解 离散之后随便拿单调队列维护一下就好了. #include<iostream> #include&l ...

随机推荐

  1. 【源码分析】你必须知道的string.IsNullOrEmpty && string.IsNullOrWhiteSpace

    写在前面 之前自信撸码时踩了一次小坑,代码如下: private static void AppServer_NewMessageReceived(WebSocketSession session, ...

  2. [css 揭秘]:CSS揭秘 技巧(二):多重边框

    我的github地址:https://github.com/FannieGirl/ifannie/ 源码都在这上面哦! 喜欢的给我一个星吧 多重边框 问题:我们通常希望在css代码层面以更灵活的方式来 ...

  3. Beta Scrum Day 6

    听说

  4. Alpha第一天

    Alpha第一天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...

  5. C语言博客作业—指针

    一.PTA实验作业 题目1: 求出数组中最大数和次最大数 1. 本题PTA提交列表 2. 设计思路 定义max表示范围数组中的最大数(初值设为a[0]),z表示找到的元素在数组中的位置: 定义指针*b ...

  6. 项目Beta冲刺Day5

    项目进展 李明皇 今天解决的进度 服务器端还未完善,所以无法进行联动调试.对页面样式和逻辑进行优化 明天安排 前后端联动调试 林翔 今天解决的进度 完成维护登录态,实现图片上传,微信开发工具上传图片不 ...

  7. RxSwift 函数响应式编程

    Max 在 Boston 上学,在 San Francisco 工作,是一名软件工程师及创业者.当他还在高中的时候就在一家创业公司工作了,他非常喜欢使用 iOS.Android 以及 JavaScri ...

  8. org.hibernate.hibernate.connection.release_mode

    org.hibernate.connection包的主要封装了通过JDBC来连接数据库的操作,用户可以以数据源的方式,或者通过特定数据库驱动的方式,甚至是自己定义连接类的方式来完成数据库的连接操作,包 ...

  9. (原创)带模板的OLE输出EXCEL

    其实带模板的OLE输出EXCEL就是将要输出的EXCEL中一些拥有固定值(如标题,表头行等)的单元格先填充好数据和设置好格式后作为模板上传到SAP 中.这样后续在输出EXCEL时只需从SAP中将模板下 ...

  10. Apache自带 ab压测工具 Windows配置使用说明 - 随笔记录

    我们先来了解一下ab工具的概念,摘自网络: ab是apache自带的压力测试工具.ab非常实用,它不仅可以对apache服务器进行网站访问压力测试,也可以对或其它类型的服务器进行压力测试.比如ngin ...