P11289 【MX-S6-T1】「KDOI-11」打印 题解
ELECTRODE_kaf · · 题解
建两个 priority queue 维护无和有印刷任务的打印机。
const ll N=2e5+10;
ll n,m;
struct item {
ll l,t,no;
} a[N];
bool cmp(item x,item y) {
return x.t<y.t;
}
pqueue(ll,greater) pq1;
struct printer {
ll no,t;
reset < (printer x) const {
if(t!=x.t) return t<x.t;
else return no<x.no;
//有任务的打印机也要选择尽可能选小编号
}
reset > (printer x) const {
if(t!=x.t) return t>x.t;
else return no>x.no;
}
};
pqueue(printer,greater) pq2;
vector<ll> ans[N];
void print1(auto x){
while(x.empty()==0){
cout<<x.top()<<' ';
x.pop();
}
}
void print2(auto x){
while(x.empty()==0){
cout<<x.top().no<<' '<<x.top().t<<'\n';
x.pop();
}
}
int main() {
// fin;
// fout;
cin>>n>>m;
rep(i,1,n) {
cin>>a[i].l>>a[i].t;
a[i].no=i;
}
sort(a+1,a+n+1,cmp);
rep(i,1,m) pq1.push(i);
rep(i,1,n){
// cout<<"pq1:";
// print1(pq1);
// cout<<"\npq2:\n";
// print2(pq2);
// endl;
// pause;
while(1){
if(pq2.empty()==0 and pq2.top().t<=a[i].t){
pq1.push(pq2.top().no);
pq2.pop();
}else break;
}
if(pq1.empty()==0){
ll cur;
xtop(cur,pq1);
ans[cur].pb(a[i].no);
printer new1;
new1.no=cur;
new1.t=a[i].t+a[i].l;
pq2.push(new1);
}else{
printer cur;
xtop(cur,pq2);
ans[cur.no].pb(a[i].no);
cur.t+=a[i].l;
//如果打印机的任务在此文件下发之前完成那它就不可能出现在 pq2 里了
pq2.push(cur);
}
}
rep(i,1,m){
//n 和 m 别弄混了
cout<<ans[i].size()<<' ';
if(ans[i].empty()==0){
sort(ans[i].begin(),ans[i].end());
//要排序,因为排序前是按照打印的先后顺序
for(ll j:ans[i]) cout<<j<<' ';
}
endl;
}
}