3 条题解

  • 2
    @ 2024-11-17 15:32:04

    本文同步于洛谷专栏,见 QAQ

    闲话:大样例以及 6060 分的数据,全都是不需要等待的情况。所以你咋写挂都能过大样例。太神秘了。

    首先将所有打印任务按照 tt 升序排序。

    注意到若不需要等待,选编号最小的。若需要等待,选等待时间最短的。看上去非常优先队列。我们开两个优先队列 q1,q2q_1,q_2 分别维护需要等待的打印机,能直接使用的打印机。维护它们的编号和可使用的时间戳。判定能否直接使用只需比较时间戳和 tt 的大小即可。

    初始化 mm 个打印机都是可直接使用的,全部放入 q2q_2 中,时间戳为 00。按照编号升序排序。

    每个打印机决策前,首先将 q1q_1 中可使用的打印机扔到 q2q_2 中,如下。

    while(wait.size() && wait.top().first <= t)
    {
        release.push(PII(wait.top().second,wait.top().first));wait.pop();
    }
    

    其中,wait 为需要等待的打印机,release 为可直接使用的打印机。waitfirst,second 分别为可使用的时间戳,打印机编号。按照时间戳升序排序。releasefirst,second 分别为为打印机编号和时间戳。按照打印机编号升序排序。

    接下来,若 q2q_2 中有元素,直接取队头即可。注意修改其时间戳。若修改后的时间戳,大于下一次任务的起始时间,就把它扔到 q1q_1 中。

    q2q_2 中没有元素,该如何处理?此时必须要等待了。我们从 q1q_1 中找到时间戳最小的打印机即可。注意,时间戳最小的打印机并不一定唯一,若有多个最小的,需使用编号最小的!

    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
    上传者