题目
N (1 <= N <= 50,000)
题解思路
将区间按左端点升序排列,然后将一层一层数轴用优先队列来处理,优先队列存储最大右端点和层数的标号(因为我们最后要得到每个区间对应的数轴编号)
因为左端点是升序的,我们让优先队列按右端点的从小到大出队。这样我们能保证,此时的队头数轴是能放的最优数轴。如果还是放不下(重叠了),就新增一个数轴并且编号即可。
AC代码
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
struct node
{
int s;
int p;
bool operator < (const node &other) const
{
return s > other.s;
}
};
priority_queue <node> q;
struct qujian
{
int r,l,z;
}a[50100];
int vis[50100];
bool cmp1 (qujian A , qujian B )
{
return A.r < B.r;
}
int main ()
{
ios::sync_with_stdio(false);
int n ;
cin>>n;
for (int i = 0 ; i < n ; i++ )
{
int t1,t2;
cin>>t1>>t2;
a[i].r = t1;
a[i].l = t2;
a[i].z = i;
}
sort(a,a+n,cmp1);
node tmp;
int sum = 1;
tmp.p = sum;
tmp.s = a[0].l;
vis[a[0].z] = sum;
q.push(tmp);
for (int i = 1 ; i < n ; i++ )
{
tmp = q.top();
if ( a[i].r <= tmp.s )
{
node tp;
sum++;
tp.s = a[i].l;
tp.p = sum;
vis[a[i].z] = sum;
q.push(tp);
}else
{
q.pop();
tmp.s = a[i].l;
vis[a[i].z] = tmp.p;
q.push(tmp);
}
}
cout<<sum<<"\n";
for (int i = 0 ; i < n ; i++ )
cout<<vis[i]<<"\n";
return 0;
}