3 条题解
-
2
本文同步于洛谷专栏,见 QAQ。
闲话:大样例以及 分的数据,全都是不需要等待的情况。所以你咋写挂都能过大样例。太神秘了。
首先将所有打印任务按照 升序排序。
注意到若不需要等待,选编号最小的。若需要等待,选等待时间最短的。看上去非常优先队列。我们开两个优先队列 分别维护需要等待的打印机,能直接使用的打印机。维护它们的编号和可使用的时间戳。判定能否直接使用只需比较时间戳和 的大小即可。
初始化 个打印机都是可直接使用的,全部放入 中,时间戳为 。按照编号升序排序。
每个打印机决策前,首先将 中可使用的打印机扔到 中,如下。
while(wait.size() && wait.top().first <= t) { release.push(PII(wait.top().second,wait.top().first));wait.pop(); }
其中,
wait
为需要等待的打印机,release
为可直接使用的打印机。wait
的first,second
分别为可使用的时间戳,打印机编号。按照时间戳升序排序。release
的first,second
分别为为打印机编号和时间戳。按照打印机编号升序排序。接下来,若 中有元素,直接取队头即可。注意修改其时间戳。若修改后的时间戳,大于下一次任务的起始时间,就把它扔到 中。
若 中没有元素,该如何处理?此时必须要等待了。我们从 中找到时间戳最小的打印机即可。注意,时间戳最小的打印机并不一定唯一,若有多个最小的,需使用编号最小的!
if(!release.size()) { priority_queue <PII,vector<PII>,greater<PII> > printer; int flag = wait.top().first; printer.push(PII(wait.top().second,wait.top()first)); wait.pop(); while(wait.top().first == flag){printer.push(PII(wait.to().second,wait.top().first));wait.pop();} release.push(PII(printer.top().first,flag)); printer.pop(); while(!printer.empty()){wait.push(PII(printer.top()second,printer.top().first));printer.pop();} }
实现略微繁琐。仅供参考。
完整代码如下。
#include <bits/stdc++.h> #define int long long using namespace std; constexpr int N = 2e5 + 10; namespace FastIO { char buf[1 << 21], *p1 = buf, *p2 = buf; #define getchar() (p1 == p2 && (p1 = buf, p2 = (p1 + fread(buf, 1, 1 << 21, stdin))) == p1 ? EOF : *p1++) template <typename T> inline T read() { T x = 0, w = 0; char ch = getchar(); while (ch < '0' || ch > '9') w |= (ch == '-'), ch = getchar(); while ('0' <= ch && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar(); return w ? -x : x; } template <typename T> inline void write(T x) { if (!x) return; write<T>(x / 10), putchar((x % 10) ^ '0'); } template <typename T> inline void print(T x) { if (x > 0) write<T>(x); else if (x < 0) putchar('-'), write<T>(-x); else putchar('0'); } template <typename T> inline void print(T x, char en) { print<T>(x), putchar(en); } }; using namespace FastIO; namespace solution { typedef pair<int,int> PII; // time,number struct ASK { int s,t,num; bool operator<(const ASK &a)const{ return t < a.t; } }; vector <ASK> ask; vector <int> ans[N]; priority_queue <PII,vector<PII>,greater<PII> > wait,release; int n,m; int tot = 0; //wait:time,number void solve() { n = read<int>(),m = read<int>(); for(int i=1;i<=n;i++) {int s,t; s = read<int>(),t = read<int>();ask.push_back({s,t,i});} for(int i=1;i<=m;i++) release.push(PII(i,0)); //number,time sort(ask.begin(),ask.end()); for(auto [s,t,num]:ask) { while(wait.size() && wait.top().first <= t){release.push(PII(wait.top().second,wait.top().first));wait.pop();} if(!release.size()) { priority_queue <PII,vector<PII>,greater<PII> > printer; int flag = wait.top().first; printer.push(PII(wait.top().second,wait.top().first)); wait.pop(); while(wait.top().first == flag){printer.push(PII(wait.top().second,wait.top().first));wait.pop();} release.push(PII(printer.top().first,flag)); printer.pop(); while(!printer.empty()){wait.push(PII(printer.top().second,printer.top().first));printer.pop();} } ans[release.top().first].push_back(num); auto tt = release.top().second; tt = max(release.top().second,t) + s; tot ++; if(tot >= n) break; if(tt > ask[tot].t) {wait.push(PII(tt,release.top().first));release.pop();} else { int number = release.top().first; release.pop(); release.push(PII(number,tt)); } } for(int i=1;i<=m;i++) sort(ans[i].begin(),ans[i].end()); // 输出前记得排个序 for(int i=1;i<=m;i++) {print(ans[i].size(),' ');for(auto t:ans[i])print(t,' '); puts("");} } } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); solution::solve(); return 0; }
信息
- ID
- 93
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 4
- 标签
- 递交数
- 1400
- 已通过
- 255
- 上传者