题解
- 我们先根据区间的左端点从小到大排序,将转折点也从小到大排序
- 然后我们加入以r为关键字的小根堆,然后就贪心
- 找到包含转折点的区间右端点离转折点最近的区间弹出,因为右端点越远,越有可能对后面的转折点提供贡献
- 注意要把右端点比转折点还小的区间弹出
代码
1 #include <queue>
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 #define N 200010
7 using namespace std;
8 struct node
9 {
10 int l,r;
11 bool operator <(const node &a) const { return r>a.r; }
12 }a[N];
13 priority_queue<node>Q;
14 int n,m,j=1,ans,d[N];
15 bool cmp(node a,node b) { return a.l==b.l?a.r<b.r:a.l<b.l; }
16 int main()
17 {
18 freopen("dream.in","r",stdin),freopen("dream.out","w",stdout),scanf("%d%d",&n,&m);
19 for (int i=1;i<=n;i++) scanf("%d%d",&a[i].l,&a[i].r);
20 for (int i=1;i<=m;i++) scanf("%d",&d[i]);
21 sort(a+1,a+n+1,cmp),sort(d+1,d+m+1);
22 for (int i=1;i<=m;i++)
23 {
24 while (j<=n&&a[j].l<=d[i]) Q.push(a[j++]);
25 while (!Q.empty()&&Q.top().r<d[i]) Q.pop();
26 if (!Q.empty()) ans++,Q.pop();
27 }
28 printf("%d",ans);
29 }