二分/堆


  求一个最小的区间使得包含所有的颜色(并不一定只出现一次)$n\leq 10^6$

  我想的做法是:二分这个最小的长度(满足单调性……好久才想到QAQ),然后O(n)判断是否有可行的区间,这一步可以用一个队列来维护,统计区间内颜色的数量(应该不难吧……)如果队首与队尾元素距离>mid就弹队首= =

  zyf有一个更加优秀的算法:用一个堆来维护左节点……还是引用吧:

 题解:
考虑到如果线段的左端点定了,那么每种肯定会选离这个端点最近的而又在这个端点右边的彩珠。
所以我们维护一个k个元素的堆,每次取出队首元素将其弹出,加入它所属种类的下一个彩珠
如果当前取出的彩珠是该种类彩珠的最后一个,那么跳出循环,输出答案。
我用的vector和priority_queue
 /**************************************************************
Problem: 1293
User: Tunix
Language: C++
Result: Accepted
Time:2608 ms
Memory:12992 kb
****************************************************************/ //Huce #1 A
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=1e6+,INF=~0u>>;
typedef long long LL;
/******************tamplate*********************/
struct data{int v,pos;}a[N];
inline bool cmp(data a,data b){return a.pos<b.pos;}
int cnt[],Q[N],n,t,tot; bool check(int x){
memset(cnt,,sizeof cnt);
int l=,r=-,num=;
F(i,,n){
Q[++r]=i;
cnt[a[Q[r]].v]++;
if (cnt[a[Q[r]].v]==) num++;
while (a[Q[r]].pos-a[Q[l]].pos>x){
cnt[a[Q[l]].v]--;
if (cnt[a[Q[l]].v]==) num--;
l++;
}
if (num==t) return ;
}
return ;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("A.in","r",stdin);
freopen("A.out","w",stdout);
#endif
n=getint(); t=getint();
int x;
F(i,,t){
x=getint();
F(j,,x){
a[++tot].v=i;
a[tot].pos=getint();
}
}
sort(a+,a+n+,cmp);
int l=,r=a[n].pos-a[].pos,mid,ans=;
while(l<=r){
mid=l+r>>;
if (check(mid)) ans=mid,r=mid-;
else l=mid+;
}
printf("%d\n",ans);
return ;
}

1293: [SCOI2009]生日礼物

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1204  Solved: 655
[Submit][Status][Discuss]

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。

Source

[Submit][Status][Discuss]

【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] 生日礼物

    传送门(bzoj) 传送门(luogu) 题目: Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应 ...

  3. BZOJ 1293 SCOI2009 生日礼物 堆

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

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

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

  5. 1293: [SCOI2009]生日礼物

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

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

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

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

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

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

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

  9. [BZOJ 1293] 生日礼物

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

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

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

随机推荐

  1. luigi学习8--使用中央调度器

    --local-scheduler一般用在开发阶段,这在一个产品中是不建议这样使用的.使用中央调度器有两个目的: 保证两个相同的task不会同时运行两次 提供一个可视化的界面 注意:中央调度器并不会帮 ...

  2. 两种会话状态之Session会话

    什么是Session 使用Cookie和附加URL参数都可以将上一次请求的状态信息传递到下一次请求中,但是如果传递的状态信息较多,将极大降低网络传输效率和增大服务器端程序处理的难度. Session技 ...

  3. C++求最小公倍数

    题目内容:求两个正整数的最小公倍数. 输入描述:输入数据含有不多于50对的数据,每对数据由两个正整数(0<n1,n2<100000)组成. 输出描述:对于每组数据n1和n2,计算最小公倍数 ...

  4. Thinkpad 小紅點設定

    因为我只需要这么多设置,所以就只写这么多了sudo gedit /etc/rc.local echo -n 240 > /sys/devices/platform/i8042/serio1/se ...

  5. Laravel 5 基础(十一)- 表单验证

    在建立一个文章的时候,如果你什么都不输入直接提交,ok,你获得了一个空的文章,没有任何错误提示,这是不对的.在命令行下运行 php artisan 可以看到一个选项 make:request,新建一个 ...

  6. 限制<input>输入内容 只允许数字 或者 字母

    只能输入数字: 有回显 <input onkeyup="value=value.replace(/[^\d]/g,'')"> 只能输入数字:无回显 <input ...

  7. Flask Web Development —— Web表单(上)

    Flask-WTF扩展使得处理web表单能获得更愉快的体验.该扩展是一个封装了与框架无关的WTForms包的Flask集成. Flask-WTF和它的依赖集可以通过pip来安装: (venv) $ p ...

  8. find your present

    Description In the present, and their card numbers are , , , , .so your present will be the one with ...

  9. 老工程升级到VS2010或以上时会出现 libc.lib 解决方法

    有些网上的工程都比较老,比如用2003之类.一般会有个静态libc.lib.在新版本里已经没有这个库,被微软无情的抛弃. 编译时会出现动态库找不到: 1>LINK : fatal error L ...

  10. swoole 异步队列

    安装步骤如下(推荐把安装文件下载到 /usr/local/src 目录下): step 1: wget --no-check-certificate https://github.com/swoole ...