BZOJ1293:[SCOI2009]生日礼物——题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1293:[SCOI2009]生日礼物——题解相关的知识,希望对你有一定的参考价值。

http://www.lydsy.com/JudgeOnline/problem.php?id=1293

https://www.luogu.org/problemnew/show/P2564#sub

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

小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。

一个很简单的单调队列,对每个彩珠位置进行排序,然后从左往右扫,开一个桶记录我们加进来的每一种彩珠的个数,同时统计加进来的彩珠种类数,当与队首相同种类的彩珠个数>=2的时候我们就可以放心把队首弹出了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=1e6+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(ch<\'0\'||ch>\'9\'){w|=ch==\'-\';ch=getchar();}
    while(ch>=\'0\'&&ch<=\'9\')X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
int n,k,m,q[N][2],p[65];
struct node{
    int pos,k;
}a[N];
bool cmp(node a,node b){
    return a.pos<b.pos;
}
int solve(){
    int l=0,r=0,ans=1e9,ok=0;
    for(int i=1;i<=m;i++){
    q[r][0]=a[i].pos;q[r++][1]=a[i].k;
    if(!p[a[i].k])ok++;
    p[a[i].k]++;
    while(l<r&&p[q[l][1]]>=2)p[q[l++][1]]--;
    if(ok==k)ans=min(ans,q[r-1][0]-q[l][0]);
    }
    return ans;
}
int main(){
    n=read(),k=read();
    for(int i=1;i<=k;i++){
    int t=read();
    for(int j=1;j<=t;j++)a[++m]=(node){read(),i};
    }
    sort(a+1,a+m+1,cmp);
    printf("%d\\n",solve());
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

以上是关于BZOJ1293:[SCOI2009]生日礼物——题解的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ-1293: [SCOI2009]生日礼物 (单调队列)

bzoj1293[SCOI2009]生日礼物 尺取法

[bzoj1293][SCOI2009]生日礼物

bzoj 1293: [SCOI2009]生日礼物

bzoj1293: [SCOI2009]生日礼物

bzoj1293: [SCOI2009]生日礼物

(c)2006-2024 SYSTEM All Rights Reserved IT常识