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;
}
posted @ 2019-06-13 17:20  lokiii  阅读(237)  评论(0编辑  收藏  举报