QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#487525 | #8793. Toilets | ucup-team4435# | WA | 0ms | 3752kb | C++20 | 7.0kb | 2024-07-22 23:02:28 | 2024-07-22 23:02:28 |
Judging History
answer
#include "bits/stdc++.h"
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i < (n); ++i)
#define rep1n(i, n) for (int i = 1; i <= (n); ++i)
#define repr(i, n) for (int i = (n) - 1; i >= 0; --i)
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define each(x, a) for (auto &x : a)
#define ar array
#define vec vector
#define range(i, n) rep(i, n)
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = double;
using str = string;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
using vpl = vector<pl>;
using vpi = vector<pair<int, int>>;
using vvi = vector<vi>;
int Bit(int mask, int b) { return (mask >> b) & 1; }
template<class T>
bool ckmin(T &a, const T &b) {
if (b < a) {
a = b;
return true;
}
return false;
}
template<class T>
bool ckmax(T &a, const T &b) {
if (b > a) {
a = b;
return true;
}
return false;
}
const int INFi = 2e9;
const int N = 5e5 + 5;
const ll INF = 2e18;
void solve() {
int n, m;
ll L;
cin >> n >> m >> L;
vl x(m);
rep(i, m) cin >> x[i];
vector<ll> t(n), p(n), s(n), d(n), v(n);
rep(i, n) {
char dirs;
cin >> t[i] >> p[i] >> dirs >> d[i];
if (dirs == '+') {
v[i] = p[i] - t[i];
s[i] = 1;
} else {
v[i] = p[i] + t[i];
s[i] = -1;
}
}
rep(i, n) {
v[i] %= L;
if (v[i] < 0) v[i] += L;
}
set<pair<ll, int>> right_q, left_q;
set<pair<ll, int>> alive;
rep(i, m) {
alive.insert({x[i], i});
}
vector<pair<ll, int>> bestL(m, {INF, -1}), bestR(m, {INF, -1});
set<ar<ll, 3>> events;
ll T = 0;
auto GetPrev = [&](int i) {
auto it = alive.find({x[i], i});
if (it == alive.begin()) it = alive.end();
return prev(it)->second;
};
auto GetNext = [&](int i) {
auto it = next(alive.find({x[i], i}));
if (it == alive.end()) it = alive.begin();
return it->second;
};
auto GetPrevRQ = [&](ll x) {
auto it = right_q.lower_bound({x, 2e9});
if (it == right_q.begin()) it = right_q.end();
return *prev(it);
};
auto GetNextLQ = [&](ll x) {
auto it = left_q.lower_bound({x, -1});
if (it == left_q.end()) it = left_q.begin();
return *it;
};
auto UpdateL = [&](int i) {
// left from i toilet
if (bestL[i].second != -1) {
events.erase({bestL[i].first, bestL[i].second, i});
}
int j = GetPrev(i);
ll rq = x[i] - T;
ll lq = x[j] - T;
lq %= L;
rq %= L;
if (lq < 0) lq += L;
if (rq < 0) rq += L;
ll len = rq - lq;
if (len <= 0) len += L;
// [lq, rq]
bestL[i] = {INF, -1};
if (!right_q.empty()) {
auto [qv, qi] = GetPrevRQ(rq + 1);
ll le = (rq - qv + L) % L;
if (le < len) {
bestL[i] = {T + le, -qi};
}
}
if (bestL[i].second != -1) {
events.insert({bestL[i].first, bestL[i].second, i});
}
};
auto UpdateR = [&](int i) {
// right from i toilet
if (bestR[i].second != -1) {
events.erase({bestR[i].first, bestR[i].second, i});
}
int j = GetNext(i);
ll lq = x[i] + T;
ll rq = x[j] + T;
lq %= L;
rq %= L;
if (lq < 0) lq += L;
if (rq < 0) rq += L;
ll len = rq - lq;
if (len <= 0) len += L;
// [lq, rq]
bestR[i] = {INF, -1};
if (!left_q.empty()) {
auto [qv, qi] = GetNextLQ(lq - 1);
ll le = (qv - lq + L) % L;
if (le < len) {
bestR[i] = {T + le, qi};
}
}
if (bestR[i].second != -1) {
events.insert({bestR[i].first, bestR[i].second, i});
}
};
auto AddPeople = [&](int i) {
if (s[i] == 1) {
// to right
right_q.insert({v[i], -i});
// right_q.insert({p[i] + L, i});
if (!alive.empty()) {
auto it = alive.lower_bound({p[i], -1});
if (it == alive.end()) it = alive.begin();
UpdateL(it->second);
}
} else {
left_q.insert({v[i], i});
// left_q.insert({p[i] + L, i});
if (!alive.empty()) {
auto it = alive.lower_bound({p[i] + 1, -1});
if (it == alive.begin()) it = alive.end();
it--;
UpdateR(it->second);
}
}
};
auto AddToilet = [&] (int i) {
alive.insert({x[i], i});
UpdateL(i);
UpdateR(i);
if (alive.size() != 1) {
UpdateL(GetNext(i));
UpdateR(GetPrev(i));
}
};
vector<pair<ll, ll>> ans(n);
auto DelToilet = [&] (int i, ll t3) {
int lq = -1, rq = -1;
if (alive.size() != 1) {
lq = GetPrev(i);
rq = GetNext(i);
}
alive.erase({x[i], i});
if (bestR[i].second != -1) {
events.erase({bestR[i].first, bestR[i].second, i});
bestR[i] = {INF, -1};
}
if (bestL[i].second != -1) {
events.erase({bestL[i].first, bestL[i].second, i});
bestL[i] = {INF, -1};
}
if (lq != -1) {
UpdateR(lq);
UpdateL(rq);
}
events.insert({t3, -1, i});
};
auto Do = [&](ll t2) {
assert(T <= t2);
while (T < t2) {
if (events.empty()) {
T = t2;
break;
}
auto [t1, who, whe] = *(events.begin());
if (t1 >= t2) {
T = t2;
break;
}
// cerr << t1 << ' ' << who << ' ' << whe << endl;
assert(T <= t1);
if (who == -1) {
T = t1;
events.erase(events.begin());
AddToilet(whe);
continue;
}
if (s[who] == 1) {
right_q.erase({v[who], -who});
} else {
left_q.erase({v[who], who});
}
ans[who] = {x[whe], t1};
DelToilet(whe, t1 + d[who]);
T = t1;
}
};
rep(i, n) {
Do(t[i]);
AddPeople(i);
}
Do(INF);
rep(i, n) {
cout << ans[i].first << ' ' << ans[i].second << '\n';
}
}
signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cout << setprecision(15) << fixed;
int t = 1;
// cin >> t;
rep(_, t) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3528kb
input:
5 3 45 10 20 30 0 0 + 200 2 5 + 10 20 40 - 100 21 16 + 10 50 0 + 22
output:
20 20 10 7 30 30 10 60 10 105
result:
ok 10 numbers
Test #2:
score: 0
Accepted
time: 0ms
memory: 3752kb
input:
1 1 1 0 0 0 - 1
output:
0 0
result:
ok 2 number(s): "0 0"
Test #3:
score: -100
Wrong Answer
time: 0ms
memory: 3532kb
input:
5 3 33 3 24 23 12 24 - 9 16 28 - 1 17 27 - 9 19 26 - 5 32 22 - 2
output:
24 12 23 21 3 41 24 54 3 51
result:
wrong answer 8th numbers differ - expected: '21', found: '54'