HDU 6003 Problem Buyer【小根堆】

任意k个都可以,也可以看做把不行的都选了,再随便选一个可以的要选的数量
把区间和m个值都排序,区间按l一序r二序排,枚举m个值,小根堆维护能帮韩当前枚举值的区间的右端点,这样方便删除区间,然后剩下的就都不行,所以ans=max(n-size+1)
注意枚举完要弹出一个区间,表示这个区间属于当前枚举值

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N=100005;
int T,n,m,a[N],ans,cas;
pair<int,int>b[N];
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>'9'||p<'0')
    {
        if(p=='-')
            f=-1;
        p=getchar();
    }
    while(p>='0'&&p<='9')
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
int main()
{
    T=read();
    while(T--)
    {
        n=read(),m=read(),ans=0;
        for(int i=1;i<=n;i++)
            b[i].first=read(),b[i].second=read();
        for(int i=1;i<=m;i++)
            a[i]=read();
        sort(a+1,a+1+m);
        sort(b+1,b+1+n);
        priority_queue<int,vector<int>,greater<int> >q;
        for(int i=1,j=1;i<=m;i++)
        {
            while(j<=n&&b[j].first<=a[i])
                q.push(b[j++].second);
            while(!q.empty()&&q.top()<a[i])
                q.pop();
            if(q.empty())
            {
                ans=-1;
                break;
            }
            ans=max(ans,n-(int)q.size()+1);
            q.pop();//!
        }
        if(ans==-1) 
            printf("Case #%d: IMPOSSIBLE!\n",++cas);
        else
            printf("Case #%d: %d\n",++cas,ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lokiii/p/11017888.html
今日推荐