比赛 |
20170912 |
评测结果 |
AAAAAAAAAA |
题目名称 |
平凡的题面 |
最终得分 |
100 |
用户昵称 |
Mayuri |
运行时间 |
0.247 s |
代码语言 |
C++ |
内存使用 |
2.61 MiB |
提交时间 |
2017-09-12 19:50:25 |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
#define mem(Arr,x) memset(Arr,x,sizeof(Arr))
const int maxN=100101;
const int inf=2147483647;
class Rang//区间or点
{
public:
int l,r;
int style;//0表示是区间,1表示是点
};
bool operator < (Rang A,Rang B)
{
if (A.l!=B.l)//保证左端点小的在前面,这样可以保证某个点被处理时能覆盖其的区间都在其前面
return A.l<B.l;
return A.style<B.style;//保证区间在点之前被处理
}
int n,m;
Rang R[maxN*2];
priority_queue<int,vector<int>,greater<int> > Q;//优先队列,小的优先
int read();
int main()
{
freopen("bg.in","r",stdin);
freopen("bg.out","w",stdout);
n=read();
m=read();
for (int i=1;i<=n;i++)
{
int u=read();
R[i].l=u;
R[i].style=1;
}
for (int i=1;i<=m;i++)
{
int l=read(),r=read();
R[i+n].l=l;
R[i+n].r=r;
R[i+n].style=0;
}
sort(&R[1],&R[n+m+1]);
int Ans=0;
for (int i=1;i<=n+m;i++)
{
if (R[i].style==0)//如果是区间,则直接放入优先队列
Q.push(R[i].r);//因为已经保证左端点单调,所以只需要放入右端点
else//如果是点,则说明能覆盖其的区间都在优先队列中了,查找是否存在这样的区间,并找出右端点最小的(贪心原理)
{
while ((!Q.empty())&&(Q.top()<R[i].l))//弹出所有冗余区间,因为排过序,所以可以保证如果此时这个区间是冗余的,后面也一定是冗余的
Q.pop();
if (!Q.empty())//因为有可能不存在,即此时队列为空,所以只有队列不为空时才说明存在能覆盖的
{
Ans++;
Q.pop();//注意弹掉这个区间,因为其已经覆盖
}
}
}
cout<<Ans<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
int read()
{
int x=0;
int k=1;
char ch=getchar();
while (((ch>'9')||(ch<'0'))&&(ch!='-'))
ch=getchar();
if (ch=='-')
{
k=-1;
ch=getchar();
}
while ((ch>='0')&&(ch<='9'))
{
x=x*10+ch-48;
ch=getchar();
}
return x*k;
}