Description
机房里有M台电脑排成一排,第i台电脑的坐标是正整数i。
现在有N个OIer进入了机房,每个OIer需要一台电脑来学tui习ji,同时每个OIer对自己电脑所处的坐标范围有一个要求区间。第i个OIer希望自己的电脑的位置≤Li或≥Ri。自然,一台电脑只能给一个OIer使用,不然会发生友♂好的跤♂流
显然,有可能这个机房无法满足所有OIer的需求。这时老师就会在机房中增加电脑。增加的电脑可以位于任意的实数位置。你需要帮老师计算一下,老师最少加几台电脑,才可以满足所有OIer的需求?
Input
第一行两个整数N,M
接下来N行,每行两个整数Li,Ri
Output
输出最小需要增加的电脑数量
Solution
贪心。 将询问按l,r作为第一、二关键字从小到大排序。 优先插进左端点,并恰好插满左端点(不能大于查询的l) 占据左边的端点的询问的丢进小根堆的优先队列。 记录一个tot表示用了1到tot号电脑。
若tot小于
L
i
L_i
Li,直接丢进优先队列。若tot等于
L
i
L_i
Li,将优先队列中右端点最小的弹出来扔到右边。
因为记录的是向右的标记(>=x) 最后从后往前ans=max(ans,后缀和-后面已有的电脑数)
Code
#include<bits/stdc++.h>
using namespace std
;
struct data
{
int l
,r
;
bool operator <(const data
&v
)const{
if(l
!=v
.l
) return l
<v
.l
;
return r
<v
.r
;
}
}a
[200010];
priority_queue
<int>q
;
int b
[200010],n
,m
;
int main(){
int x
,y
,tot
=0;
scanf("%d%d",&n
,&m
);
for(int i
=1;i
<=n
;i
++)
scanf("%d%d",&a
[i
].l
,&a
[i
].r
);
for(int i
=1;i
<=m
;i
++) b
[i
]=-1;
sort(a
+1,a
+n
+1);
for(int i
=1;i
<=n
;i
++){
if(a
[i
].l
==0){
b
[a
[i
].r
]++;
continue;
}
if(a
[i
].l
==tot
){
int x
=q
.top();
q
.pop();
b
[-x
]++;
q
.push(-a
[i
].r
);
continue;
}
b
[++tot
]++;
q
.push(-a
[i
].r
);
}
int ans
=0,sum
=0;
for(int i
=m
+1;i
>-1;i
--){
sum
+=b
[i
];
ans
=max(ans
,sum
);
}
printf("%d",ans
);
}