• Codeforces 1239C. Queue in the Train


    传送门

    事实上就是模拟

    搞一个优先队列维护一下事件结构体:时间,人的编号,入队还是出队

    再维护两个 $set$ ,队列内的人 $inQueue$ ,想要进入队列内的人 $want$

    然后模拟模拟模拟!

    初始把所有入队事件塞到优先队列,顺便维护一下当前最后一个取完水的时刻

    每次取出优先队列里面时间最小的,时间相同优先取入队的,同时间都入队优先取编号小的

    然后如果是入队,那么看看当前队列内编号最小的比较一下编号,然后根据比较结果看看是直接入队还是先塞到 $want$ 里面

    如果是出队,直接更新一下答案和队列,然后看看 $want$ 里面有没有人能入队

    然后就做完了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<set>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2e5+7;
    int n,P;
    ll ans[N];
    struct dat {
        ll tim; int id; bool flag;
        dat (ll _tim=0,int _id=0,bool _flag=0) { tim=_tim,id=_id,flag=_flag; }
        inline bool operator < (const dat &tmp) const {
            if(tim!=tmp.tim) return tim>tmp.tim;
            return flag!=tmp.flag ? flag>tmp.flag : id>tmp.id;
        }
    }D[N];
    priority_queue <dat> Q;
    set <int> inQ,wnt;
    int main()
    {
        n=read(),P=read();
        for(int i=1;i<=n;i++) D[i]=dat(read(),i,0);
        for(int i=1;i<=n;i++) Q.push(D[i]);
        ll las=0;
        while(!Q.empty())
        {
            dat t=Q.top(); Q.pop();
            if(!t.flag)
            {
                if(inQ.empty()||*inQ.begin()>t.id)
                {
                    las=max(las,t.tim),Q.push(dat(las+P,t.id,1));
                    inQ.insert(t.id); las+=P;
                }
                else wnt.insert(t.id);
                continue;
            }
            ans[t.id]=t.tim; inQ.erase(t.id);
            if(!wnt.empty() && (inQ.empty()||*inQ.begin()>*wnt.begin()))
            {
                auto p=wnt.begin(); inQ.insert(*p);
                Q.push(dat(las+P,*p,1)); las+=P; wnt.erase(p);
            }
        }
        for(int i=1;i<=n;i++) printf("%lld ",ans[i]); puts("");
        return 0;
    }
  • 相关阅读:
    下载android的linux内核的方法
    安装sunjava5jdk 提示"无法找到软件包sunjava5jdk
    Linux kernel中的annotation(转)
    2012年计划
    Android 开机图片/文字/动画的修改(转)
    2.6 内核中的计时器和列表
    linux设置默认网关
    谷歌Android被Linux内核除名(转)
    使用call_usermodehelper在Linux内核中直接运行用户空间程序(转)
    S3C2410平台上运行为例,讲解内核的解压过程
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11719230.html
Copyright © 2020-2023  润新知