Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Think in terms of absolute finishing time, not just “which bus should I take first”. If you board a bus at position at time , that bus reaches any later position exactly according to its own schedule; your previous walking/waiting only decides whether you can be there by then.
For one bus , what positions can still catch it? A person starting at can meet the bus somewhere between and iff and they can reach the bus line in time. Since , this becomes a simple interval of starting positions, not a complicated curve.
If a person catches bus , the best outcome from that bus is: ride until , then continue optimally from . So each bus offers a candidate value to every catchable , and the catchability condition can be expressed as one threshold inequality.
For a state “at position at time ”, define the key . Bus is catchable iff where Initial people have key .
Each bus creates a new state at its endpoint with key Process buses in decreasing . Keep already-computed bus answers in a Fenwick tree keyed by , supporting prefix minimum queries for all buses with . Compare against walking after the bus stops.
We need answer many queries: starting at position , what is the earliest possible time to reach ell?
The trap is pretending this is just “take the best bus by coordinate.” Nope. Time matters. A bus might be physically useful-looking, but if it already passed, tough luck.
The state key
Suppose at some moment you are at position at time . Can you catch bus ?
The bus starts at at time , moves with speed , and stops at . If you meet it at position , then the bus reaches at time
You can reach by then iff
For catching a bus that is ahead / to your right, the limiting case is whether you can meet it by the time it reaches its final stop :
Multiply by :
Rearrange:
So define:
and for each bus:
Then the bus is catchable exactly when
That is the whole sauce. One threshold. No geometry circus.
For an initial person at position , time is , so their key is simply
What happens after taking a bus?
If you catch bus , no matter where you boarded it, it reaches at absolute time
So riding bus puts you into a new state:
Its key is
From there, either walk to the end, or catch another bus whose threshold is at most this .
Let be the minimum final arrival time if you have caught bus and ride it to its endpoint. Then:
The first term means: ride this bus, then walk. The second term means: ride this bus, then transfer to some other useful bus.
Why processing order works
For a bus :
while its own catch threshold is
So
Taking buses moves you to a strictly “larger” key. Therefore, if we process buses in decreasing , all buses you could transfer to from the current endpoint are already available in the data structure.
This is the greedy/sorting part. The sorting is doing real work, not just looking pretty for the compiler.
Data structure
Each computed bus contributes:
For a query key , we need:
That is a prefix minimum query. Coordinate-compress all values and use a Fenwick tree storing minimums.
For each bus in decreasing :
For each person at position :
Walking is always legal, so even if no bus is useful, the answer is fine.
Complexity
Sorting and Fenwick operations give:
Memory is . Clean enough for without doing anything cursed.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
struct FenwickMin {
int n;
vector<long double> bit;
static constexpr long double INF = 1e100L;
FenwickMin(int n = 0) { init(n); }
void init(int n_) {
n = n_;
bit.assign(n + 1, INF);
}
void update(int idx, long double val) {
for (; idx <= n; idx += idx & -idx) bit[idx] = min(bit[idx], val);
}
long double query(int idx) const {
long double res = INF;
for (; idx > 0; idx -= idx & -idx) res = min(res, bit[idx]);
return res;
}
};
struct Bus {
ll s, t;
ll a, q;
};
int main() {
setIO();
int n, m;
ll l, x, y;
cin >> n >> m >> l >> x >> y;
vector<Bus> buses(n);
vector<ll> coords;
coords.reserve(n);
for (auto &b : buses) {
cin >> b.s >> b.t;
b.a = (x - y) * b.t + y * b.s;
b.q = x * b.t + y * (b.t - b.s);
coords.push_back(b.a);
}
sort(coords.begin(), coords.end());
coords.erase(unique(coords.begin(), coords.end()), coords.end());
sort(buses.begin(), buses.end(), [](const Bus &u, const Bus &v) {
return u.q > v.q;
});
FenwickMin fw((int)coords.size());
for (const auto &b : buses) {
int upto = upper_bound(coords.begin(), coords.end(), b.q) - coords.begin();
long double best = fw.query(upto);
long double walk_after = (long double)(b.t - b.s) / x + (long double)(l - b.t) / y;
best = min(best, walk_after);
int idx = lower_bound(coords.begin(), coords.end(), b.a) - coords.begin() + 1;
fw.update(idx, best);
}
cout << fixed << setprecision(12);
while (m--) {
ll p;
cin >> p;
ll key = x * p;
int upto = upper_bound(coords.begin(), coords.end(), key) - coords.begin();
long double ans = min((long double)(l - p) / y, fw.query(upto));
cout << (double)ans << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
struct FenwickMin {
int n;
vector<long double> bit;
static constexpr long double INF = 1e100L;
FenwickMin(int n = 0) { init(n); }
void init(int n_) {
n = n_;
bit.assign(n + 1, INF);
}
void update(int idx, long double val) {
for (; idx <= n; idx += idx & -idx) bit[idx] = min(bit[idx], val);
}
long double query(int idx) const {
long double res = INF;
for (; idx > 0; idx -= idx & -idx) res = min(res, bit[idx]);
return res;
}
};
struct Bus {
ll s, t;
ll a, q;
};
int main() {
setIO();
int n, m;
ll l, x, y;
cin >> n >> m >> l >> x >> y;
vector<Bus> buses(n);
vector<ll> coords;
coords.reserve(n);
for (auto &b : buses) {
cin >> b.s >> b.t;
b.a = (x - y) * b.t + y * b.s;
b.q = x * b.t + y * (b.t - b.s);
coords.push_back(b.a);
}
sort(coords.begin(), coords.end());
coords.erase(unique(coords.begin(), coords.end()), coords.end());
sort(buses.begin(), buses.end(), [](const Bus &u, const Bus &v) {
return u.q > v.q;
});
FenwickMin fw((int)coords.size());
for (const auto &b : buses) {
int upto = upper_bound(coords.begin(), coords.end(), b.q) - coords.begin();
long double best = fw.query(upto);
long double walk_after = (long double)(b.t - b.s) / x + (long double)(l - b.t) / y;
best = min(best, walk_after);
int idx = lower_bound(coords.begin(), coords.end(), b.a) - coords.begin() + 1;
fw.update(idx, best);
}
cout << fixed << setprecision(12);
while (m--) {
ll p;
cin >> p;
ll key = x * p;
int upto = upper_bound(coords.begin(), coords.end(), key) - coords.begin();
long double ans = min((long double)(l - p) / y, fw.query(upto));
cout << (double)ans << '\n';
}
return 0;
}