公式
D - Long Waiting 解説
by
D - Long Waiting 解説
by
sheyasutaka
実装方針
団体客 \(i-1\) が入店するまでを処理したものとし,その時刻を \(T_{i-1}\) とおきます.
団体客 \(i\) が先頭に来る時刻 \(A'_i\) は \(\max(T_{i-1}, A_i)\) によって得られます.
この時点で,まだ退店していない客の人数合計が \(K\) 以下であれば,その時刻がそのまま団体客 \(i\) の入店時刻になります. そうでなければ,人数合計が \(K\) 以下になるまで,退店時刻が最も早い客を取り除くことを繰り返します.そして,\(A'_i\) と退店時刻との最大値が団体客 \(i\) の入店時刻とわかります.
退店時刻が最も早い客を取得するのは,優先度付きキューと呼ばれるデータ構造によって実現可能です.C++ などの主な言語においては標準で用意されているので,それを使用するのがよいでしょう.
現時点で退店していない客の人数合計は,客の入店ごとに人数合計を増やし,退店ごとに人数合計を減らすことで差分更新が可能です.
実装例 (C++)
#include <iostream>
using std::cin;
using std::cout;
#include <vector>
using std::vector;
using std::pair;
#include <queue>
using std::priority_queue;
using std::greater;
using std::max;
typedef long long int ll;
typedef pair<ll, ll> P;
ll n, k;
vector<ll> a, b, c;
void solve () {
priority_queue<P, vector<P>, greater<P> > que;
vector<ll> ans(n, -1);
ll sum = 0;
ll t = 0;
for (ll i = 0; i < n; i++) {
t = max(t, a[i]);
while (sum + c[i] > k) {
P q = que.top(); que.pop();
t = max(t, q.first);
sum -= q.second;
}
ans[i] = t;
que.push({t + b[i], c[i]});
sum += c[i];
}
for (ll i = 0; i < n; i++) {
cout << ans[i] << "\n";
}
}
int main (void) {
cin >> n >> k;
a.resize(n);
b.resize(n);
c.resize(n);
for (ll i = 0; i < n; i++) {
cin >> a[i] >> b[i] >> c[i];
}
solve();
return 0;
}
投稿日時:
最終更新: