[SCOI2009]生日礼物
2013-10-30 21:24
369 查看
如有错误,请留言提醒,不要坑到小朋友
小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。
Input
6 3
1 5
2 1 7
3 1 3 8
[b]Output
[/b]
3
我们用小根堆来维护彩带的左端点,右端点就是堆中元素的最大值。由于题目给出的每一种小球的坐标单调递增,所以很好求出每个球最近的下一个同类球是哪个。题目要求所有小球都必须在彩带上,就是说堆内的元素必须为K个,所以我们先将每种球的坐标最小的放进堆里,并且记录初始答案,然后每次删除堆顶,为了维持堆里的元素个数,所以我们还要插入一个与删除元素相同种类的下一个球,就可更新答案了,当没有同种球可以插入时,就可以结束了。
在这里有人会有疑惑了,为什么这种球没了,不能改变其他的球来更新答案呢? 原因很简单,因为,插入其他的球,并不会改变堆顶,也就是说不会改变最小值,而只可能会让最大值变大,所以不可能在得到最优解。
还有人有疑惑,堆中元素的最大值怎么求呢? 其实,最大值就是所有进入过堆的元素的最大值,因为我们每次只将最小值删除,而不影响最大值,最大值是不断变大的。
总的时间复杂度为:O(NlogN),足以在一秒的时间内解决了。
小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。
Input
6 3
1 5
2 1 7
3 1 3 8
[b]Output
[/b]
3
我们用小根堆来维护彩带的左端点,右端点就是堆中元素的最大值。由于题目给出的每一种小球的坐标单调递增,所以很好求出每个球最近的下一个同类球是哪个。题目要求所有小球都必须在彩带上,就是说堆内的元素必须为K个,所以我们先将每种球的坐标最小的放进堆里,并且记录初始答案,然后每次删除堆顶,为了维持堆里的元素个数,所以我们还要插入一个与删除元素相同种类的下一个球,就可更新答案了,当没有同种球可以插入时,就可以结束了。
在这里有人会有疑惑了,为什么这种球没了,不能改变其他的球来更新答案呢? 原因很简单,因为,插入其他的球,并不会改变堆顶,也就是说不会改变最小值,而只可能会让最大值变大,所以不可能在得到最优解。
还有人有疑惑,堆中元素的最大值怎么求呢? 其实,最大值就是所有进入过堆的元素的最大值,因为我们每次只将最小值删除,而不影响最大值,最大值是不断变大的。
总的时间复杂度为:O(NlogN),足以在一秒的时间内解决了。
#include<cstdlib> #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<queue> #define maxn 61 #define maxp 1000010 #define maxx 1000010 using namespace std; typedef pair<int,int> PII; inline int read(){ int tmp=0;char ch; while(ch=getchar())if('0'<=ch&&ch<='9')break; for(;'0'<=ch&&ch<='9';ch=getchar())tmp=tmp*10+ch-'0'; return tmp; } PII aa[maxx]; int tot,f[maxn],sum,n,k,ans=0x7fffffff; priority_queue<PII,vector<PII>,greater<PII> >q; int main(){ scanf("%d%d",&n,&k); for(int i=1;i<=k;i++){ int t=read(); for(int j=1;j<=t;j++){ int b=read(); aa[tot+j]=make_pair(b,i); } tot+=t; } // printf("%d\n",tot); sort(aa+1,aa+tot+1); for(int i=1;i<=tot;i++){ q.push(aa[i]); if(!f[aa[i].second])sum++; f[aa[i].second]=aa[i].first; while(f[q.top().second]!=q.top().first)q.pop(); if(sum==k){ans=min(ans,aa[i].first-q.top().first);} // printf("%d %d %d %d %d\n",ans,aa[i].first,aa[i].second,q.top().first,q.top().second); } printf("%d\n",ans); // system("pause"); }
var h,fir,e:array[0..60] of longint; next,num,data:array[0..1000000] of longint; n,k,tot,i,j,len,sum,a,ans,max:longint; procedure ins(x,xx:longint); var now,fa,t:longint; begin inc(len); h[len]:=x; e[len]:=xx; now:=len; fa:=now div 2; while now>1 do begin if h[now]<h[fa] then begin t:=h[now]; h[now]:=h[fa]; h[fa]:=t; t:=e[now]; e[now]:=e[fa]; e[fa]:=t; now:=fa; fa:=fa div 2; end else break; end; end; procedure del; var now,son,t:longint; begin h[1]:=h[len]; e[1]:=e[len]; dec(len); now:=1; while now<=len do begin if h[now*2]<h[now*2+1] then son:=now*2 else son:=now*2+1; if (son<=len) and (h[now]>h[son]) then begin t:=h[now]; h[now]:=h[son]; h[son]:=t; t:=e[now]; e[now]:=e[son]; e[son]:=t; now:=son; end else break; end; end; begin readln(n,k); tot:=0; len:=0; max:=0; for i:=1 to k do begin read(sum); inc(tot); read(data[tot]); fir[i]:=tot; for j:=2 to sum do begin inc(tot); read(data[tot]); next[tot-1]:=tot; end; end; for i:=1 to k do begin ins(data[fir[i]],fir[i]); if max<data[fir[i]] then max:=data[fir[i]]; end; ans:=max-h[1]; while true do begin if next[e[1]]=0 then break; a:=e[1]; del; ins(data[next[a]],next[a]); if max<data[next[a]] then max:=data[next[a]]; if ans>max-h[1] then ans:=max-h[1]; end; writeln(ans); end.
相关文章推荐
- [bzoj 1293][SCOI2009] 生日礼物
- [BZOJ 1293][SCOI2009]生日礼物:单调队列
- 【BZOJ】1293 [SCOI2009]生日礼物 (这题有多种解法)
- [luoguP2564][SCOI2009]生日礼物(队列)
- BZOJ1293: [SCOI2009]生日礼物
- 数据结构(堆):SCOI 2009 生日礼物
- 【bzoj1293】【SCOI2009】【生日礼物】
- BZOJ1293: [SCOI2009]生日礼物
- [BZOJ1293]SCOI2009生日礼物|贪心
- 【SCOI 2009】生日礼物
- BZOJ 1293: [SCOI2009]生日礼物
- [bzoj1293][SCOI2009]生日礼物(莫队)
- 【BZOJ 1293】【SCOI 2009】生日礼物
- bzoj 1293: [SCOI2009]生日礼物
- bzoj 1293: [SCOI2009]生日礼物 STL
- bzoj1293 [SCOI2009]生日礼物
- BZOJ 1293: [SCOI2009]生日礼物【毛毛虫】
- bzoj 1293: [SCOI2009]生日礼物
- bzoj1293: [SCOI2009]生日礼物 单调队列
- BZOJ1293: [SCOI2009]生日礼物