luogu2564 [SCOI2009]生日礼物

Posted poorpool

tags:

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

排序枚举左端点,则右端点必定不降

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct Node{
    int pos, val;
}nd[1000005];
int n, k, cnt[63], uu, vv=0, rig=0, re=0, ans=0x3f3f3f3f;
void rn(int &x){
    x = 0;
    char ch=getchar();
    while(ch<‘0‘ || ch>‘9‘) ch = getchar();
    while(ch>=‘0‘ && ch<=‘9‘){
        x = x * 10 + ch - ‘0‘;
        ch = getchar();
    }
}
bool cmp(Node x, Node y){
    return x.pos<y.pos;
}
int main(){
    rn(n); rn(k);
    for(int i=1; i<=k; i++){
        rn(uu);
        for(int j=1; j<=uu; j++){
            rn(nd[++vv].pos);
            nd[vv].val = i;
        }
    }
    sort(nd+1, nd+1+vv, cmp);
    for(int i=1; i<=n; i++){
        while(re<k && rig<n){
            rig++;
            if(++cnt[nd[rig].val]==1)
                re++;
        }
        if(re==k)
            ans = min(ans, nd[rig].pos-nd[i].pos);
        if(--cnt[nd[i].val]==0) re--;
    }
    cout<<ans<<endl;
    return 0;
}

当然也可以用滑动窗口的思想做,就是比较慢

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct Node{
    int pos, val;
}nd[1000005];
int n, k, cnt[63], uu, vv=0, lev=1, rig=0, a[1000005];
void rn(int &x){
    x = 0;
    char ch=getchar();
    while(ch<‘0‘ || ch>‘9‘) ch = getchar();
    while(ch>=‘0‘ && ch<=‘9‘){
        x = x * 10 + ch - ‘0‘;
        ch = getchar();
    }
}
bool cmp(Node x, Node y){
    return x.pos<y.pos;
}
bool check(int lim){
    memset(cnt, 0, sizeof(cnt));
    lev = 1, rig = 0;
    int re=0;
    for(int i=1; i<=n; i++){
        while(lev<=rig && nd[a[lev]].pos<nd[i].pos-lim){
            if(--cnt[nd[a[lev]].val]==0)    re--;
            lev++;
        }
        a[++rig] = i;
        if(++cnt[nd[i].val]==1) re++;
        if(re==k)   return true;
    }
    return false;
}
int main(){
    rn(n); rn(k);
    for(int i=1; i<=k; i++){
        rn(uu);
        for(int j=1; j<=uu; j++){
            rn(nd[++vv].pos);
            nd[vv].val = i;
        }
    }
    sort(nd+1, nd+1+vv, cmp);
    int l=0, r=nd[vv].pos, mid, ans=0;
    while(l<=r){
        mid = (l + r) >> 1;
        if(check(mid)){
            ans = mid;
            r = mid - 1;
        }
        else    l = mid + 1;
    }
    cout<<ans<<endl;
    return 0;
}

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

P2564 [SCOI2009]生日礼物?

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

[SCOI2009]生日礼物(尺取法)

BZOJ1293: [SCOI2009]生日礼物

BZOJ 1293: [SCOI2009]生日礼物 贪心

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