Untitled
unknown
c_cpp
2 years ago
4.5 kB
7
Indexable
#include <bits/stdc++.h>
struct Guest {
int arrive, size, duration, id;
Guest() : arrive(), size(), duration(), id() {}
Guest(int a, int s, int d, int i) : arrive(a), size(s), duration(d), id(i) {}
};
struct Table {
int size, releaseTime;
Table(int s, int r) : size(s), releaseTime(r) {}
};
// comparator of waiting_time
auto cmp_t = [] (Guest a, Guest b) {
return a.arrive < b.arrive;
};
// comparator of waiting_size
auto cmp_s = [] (Guest a, Guest b) {
if (a.size != b.size) return a.size > b.size;
else return a.arrive < b.arrive;
};
// comparator of release
auto cmp_r = [] (Table a, Table b) {
return a.releaseTime < b.releaseTime;
};
std::set<Guest, decltype(cmp_t)> waiting_time(cmp_t); // early->last
std::set<Guest, decltype(cmp_s)> waiting_size(cmp_s); // 1. large->small, 2. early->last
std::multiset<Table, decltype(cmp_r)> release_list(cmp_r); // early->last
std::map<int, int> available_table; // unused table <table size, # of table>
Guest guestInput[200005];
int ans[200005];
void Assign(int time);
void Release(int time);
int main() {
int N, M;
std::cin >> N >> M;
for (int i = 0; i < N; i++) {
int arrive, size, duration;
std::cin >> arrive >> size >> duration;
guestInput[i] = Guest(arrive, size, duration, i);
}
while (M--) {
int size, num;
std::cin >> size >> num;
available_table.insert({size, num});
}
for (int i = 0; i < N; i++) {
Release(guestInput[i].arrive - 1);
waiting_size.insert(guestInput[i]);
waiting_time.insert(guestInput[i]);
Release(guestInput[i].arrive);
Assign(guestInput[i].arrive);
}
while (waiting_time.size()) Release(INT_MAX);
for (int i = 0; i < N; i++) std::cout << ans[i] << '\n';
}
void Assign(int time) {
while (waiting_time.size() && available_table.size()) {
// search the targetGuest
Guest targetGuest = *waiting_time.begin();
// search the min table
auto targetTable = available_table.lower_bound(targetGuest.size);
// search the max-size table
auto maxTable = available_table.rbegin();
if (targetTable != available_table.end()) {
// record the answer
ans[targetGuest.id] = time;
// update waiting_size
waiting_size.erase(targetGuest);
// update waiting_time
waiting_time.erase(targetGuest);
// updeate release_list
release_list.insert(Table(targetTable->first, time + targetGuest.duration));
// updeate available_table
targetTable->second--;
if (targetTable->second <= 0) available_table.erase(targetTable);
}
else if(maxTable->first >= waiting_size.rbegin()->size) {
// search the targetGuest
targetGuest = *waiting_size.upper_bound(Guest(-1, maxTable->first, 0, 0));
// search the min table
targetTable = available_table.lower_bound(targetGuest.size);
// record the answer
ans[targetGuest.id] = time;
// update waiting_size
waiting_size.erase(targetGuest);
// update waiting_time
waiting_time.erase(targetGuest);
// updeate release_list
release_list.insert(Table(targetTable->first, time + targetGuest.duration));
// updeate available_table
targetTable->second--;
if (targetTable->second <= 0) available_table.erase(targetTable);
}
else break;
}
}
void Release(int time) {
while (release_list.size() && release_list.begin()->releaseTime <= time) {
int sameTime = release_list.begin()->releaseTime;
// release table for the same time
while (release_list.begin()->releaseTime == sameTime) {
int size = release_list.begin()->size;
// updeate release_list
release_list.erase(release_list.begin());
// updeate available_table
if (available_table.find(size) == available_table.end())
available_table.insert({size, 1});
else available_table[size]++;
}
// try assign after each release
Assign(sameTime);
}
}Editor is loading...
Leave a Comment