E - Third-Party Software - 2
一开始,我想的是按线段长度来排序,但是无法判断是否全覆盖1~m个区间
正确的作法应该先按开始端点升序,如果相等则末端点降序
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
struct node
{
int a, b, id;
friend bool operator <(const node &r, const node &w)
{
if(r.a != w.a)
return r.a < w.a;
else
return r.b > w.b;
}
}t[N];
vector<int> ans;
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%d %d", &t[i].a, &t[i].b), t[i].id = i;
sort(t + 1, t + 1 + n);
if(t[1].a != 1)
{
cout << "NO\n";
return 0;
}
ans.push_back(t[1].id);
int j = t[1].b;
for(int i = 2; i <= n;)
{
if(j >= t[i].a - 1)
{
int p = j, u = t[i].id;
while(i <= n && j >= t[i].a - 1)//找出最优区间
{
if(t[i].b > p) //表示该区间不是已经选的区间的子集
{
u = t[i].id;
p = t[i].b;
}
i++;
}
if(j == p)continue;
j = p;
ans.push_back(u);
}
else
{
cout << "NO\n";
return 0;
}
}
if(j < m)
{
cout << "NO\n";
return 0;
}
cout << "YES\n" << ans.size() << endl;
for(vector<int>::iterator it = ans.begin(); it != ans.end(); it++)
printf("%d ", *it);
printf("\n");
return 0;
}

浙公网安备 33010602011771号