Codeforces Round #594 (Div. 1) C. Queue in the Train 模拟
C. Queue in the Train
There are 𝑛 seats in the train's car and there is exactly one passenger occupying every seat. The seats are numbered from 1 to 𝑛 from left to right. The trip is long, so each passenger will become hungry at some moment of time and will go to take boiled water for his noodles. The person at seat 𝑖 (1≤𝑖≤𝑛) will decide to go for boiled water at minute 𝑡𝑖.
Tank with a boiled water is located to the left of the 1-st seat. In case too many passengers will go for boiled water simultaneously, they will form a queue, since there can be only one passenger using the tank at each particular moment of time. Each passenger uses the tank for exactly 𝑝 minutes. We assume that the time it takes passengers to go from their seat to the tank is negligibly small.
Nobody likes to stand in a queue. So when the passenger occupying the 𝑖-th seat wants to go for a boiled water, he will first take a look on all seats from 1 to 𝑖−1. In case at least one of those seats is empty, he assumes that those people are standing in a queue right now, so he would be better seating for the time being. However, at the very first moment he observes that all seats with numbers smaller than 𝑖 are busy, he will go to the tank.
There is an unspoken rule, that in case at some moment several people can go to the tank, than only the leftmost of them (that is, seating on the seat with smallest number) will go to the tank, while all others will wait for the next moment.
Your goal is to find for each passenger, when he will receive the boiled water for his noodles.
Input
The first line contains integers 𝑛 and 𝑝 (1≤𝑛≤100000, 1≤𝑝≤109) — the number of people and the amount of time one person uses the tank.
The second line contains 𝑛 integers 𝑡1,𝑡2,…,𝑡𝑛 (0≤𝑡𝑖≤109) — the moments when the corresponding passenger will go for the boiled water.
Output
Print 𝑛 integers, where 𝑖-th of them is the time moment the passenger on 𝑖-th seat will receive his boiled water.
Example
input
5 314
0 310 942 628 0
output
314 628 1256 942 1570
Note
Consider the example.
At the 0-th minute there were two passengers willing to go for a water, passenger 1 and 5, so the first passenger has gone first, and returned at the 314-th minute. At this moment the passenger 2 was already willing to go for the water, so the passenger 2 has gone next, and so on. In the end, 5-th passenger was last to receive the boiled water.
题意
火车上面一共有n个人要打水,每个人会选择在t[i]的时间去打水,每次打水需要花费p的代价。每个人都不喜欢排队,如果这个人发现他前面有人没在座位上,他就不会去打水;如果有多个人同时去打水,序号小的会优先去排队;排队按照先后顺序打水。
题解
纯模拟题,维护一个打水的优先队列,维护一个排队的队列,维护一个等待序列。
然后模拟模拟就好了。 那么问题来了,这道题真的值div1 C的难度吗
代码
#include<bits/stdc++.h>
using namespace std;
priority_queue<pair<long long,int> >Q1;
priority_queue<int> Q2;
set<int> EmptyQueue;
queue<int>Q3;
const int maxn = 1e5+7;
int n;
long long p;
long long ans[maxn];
int main(){
scanf("%d%lld",&n,&p);
for(int i=0;i<n;i++){
long long t;
scanf("%lld",&t);
Q1.push(make_pair(-t,-i));
}
long long now = 0;
while(!Q1.empty()||!Q2.empty()||!Q3.empty()){
if(Q3.empty()&&Q2.empty()){
now = max(now,-Q1.top().first);
}
while(!Q1.empty()&& -Q1.top().first<=now+p){
if(EmptyQueue.empty()||(*EmptyQueue.begin()>-Q1.top().second)){
Q3.push(-Q1.top().second);
EmptyQueue.insert(-Q1.top().second);
} else {
Q2.push(Q1.top().second);
}
Q1.pop();
}
if(!Q3.empty()){
ans[Q3.front()]=now+p;
now=now+p;
EmptyQueue.erase(Q3.front());
Q3.pop();
}
if(!Q2.empty()&&Q3.empty()){
Q3.push(-Q2.top());
EmptyQueue.insert(-Q2.top());
Q2.pop();
}
}
for(int i=0;i<n;i++)
cout<<ans[i]<<" ";
cout<<endl;
}