CSUSTOJ 你真的会泡面吗?(优先队列模拟)

CSUSTOJ 你真的会泡面吗?(优先队列模拟)_第1张图片

思路:
用两个优先队列模拟就好了

#pragma GCC optimize(2)
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
const int maxn = 2e5 + 7;
const int mod = 1e9 + 7;
ll E[maxn],S[maxn],T[maxn];
int n;

struct Node1 { //按到来的时间和剩余时间和编号排序
    int id;
    ll tim,res;
    bool operator < (const Node1&rhs) const {
        if(tim != rhs.tim) {
            return tim > rhs.tim;
        }
        if(res != rhs.res) {
            return res > rhs.res;
        }
        if(id != rhs.id) {
            return id > rhs.id;
        }
        return true;
    }
};

struct Node2 { //按剩余时间和编号排序
    int id;
    ll tim,res;
    bool operator < (const Node2&rhs) const {
        if(res != rhs.res) {
            return res > rhs.res;
        }
        if(id != rhs.id) {
            return id > rhs.id;
        }
        return true;
    }
};

priority_queue<Node1>q; //到来的时间优先
priority_queue<Node2>p; //剩余的时间优先

int main() {
    scanf("%d",&n);
    for(int i = 1;i <= n;i++) {
        scanf("%lld%lld",&S[i],&T[i]);
        q.push({i,S[i],T[i]});
    }
    ll tim = 0;//泡面花了多少时间
    ll pre = 0;
    while(!q.empty()) {
        Node1 now = q.top();q.pop();
        ll num = now.tim - pre; //两次间隔的时间
        if(!p.empty()) {
            while(!p.empty() && num >= p.top().res) {
                E[p.top().id] += (p.top().res + tim) % mod;
                tim += p.top().res;
                num -= p.top().res;
                p.pop();
            }
            tim += num;
            if(num && !p.empty()) {
                Node2 tp = p.top();p.pop();
                tp.res -= num;
                p.push(tp);
            }
        } else {
            tim += num;
        }
        pre = now.tim;
        p.push(Node2{now.id,now.tim,now.res});
        while(!q.empty() && q.top().tim == now.tim) {
            now = q.top();q.pop();
            p.push(Node2{now.id,now.tim,now.res});
        }
    }
    
    while(!p.empty()) {
        Node2 now = p.top();p.pop();
        E[now.id] = (now.res + tim) % mod;
        tim += now.res;
    }
    
    ll ans = 0;
    for(int i = 1;i <= n;i++) {
//        printf("FUCK %lld\n",E[i]);
        ans += E[i] - S[i] - T[i];
        ans %= mod;
    }
    
    ans = ((ans % mod) + mod) % mod;
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(#,长理选拔赛)