#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class a, class b> ostream& operator<<(ostream &l, const pair<a, b> &r) {
l << "(" << r.first << ", " << r.second << ")";
return l;
}
template <class t, unsigned long int s> ostream& operator<<(ostream &l, const array<t, s> &r) {
l << "[";
for (int i = 0; i + 1 < s; i++) l << r[i] << ", ";
if (s > 0) l << r[s - 1];
l << "]";
return l;
}
template <class t> ostream& operator<<(ostream &l, const vector<t> &r) {
l << "{";
for (int i = 0; i + 1 < r.size(); i++) l << r[i] << ", ";
if (!r.empty()) l << r.back();
l << "}";
return l;
}
// kactl
struct Line {
mutable ll k, m, p;
bool operator<(const Line& o) const { return k < o.k; }
bool operator<(ll x) const { return p < x; }
};
struct LineContainer : multiset<Line, less<>> {
// (for doubles, use inf = 1/.0, div(a,b) = a/b)
static const ll inf = LLONG_MAX;
ll div(ll a, ll b) { // floored division
return a / b - ((a ^ b) < 0 && a % b); }
bool isect(iterator x, iterator y) {
if (y == end()) return x->p = inf, 0;
if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
else x->p = div(y->m - x->m, x->k - y->k);
return x->p >= y->p;
}
void add(ll k, ll m) {
auto z = insert({k, m, 0}), y = z++, x = y;
while (isect(y, z)) z = erase(z);
if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
while ((y = x) != begin() && (--x)->p >= y->p)
isect(x, erase(y));
}
ll query(ll x) {
assert(!empty());
auto l = *lower_bound(x);
return l.k * x + l.m;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
ll x, t;
int n, m, w;
cin >> x >> n >> m >> w >> t;
vector<pair<ll, ll>> a(n + 1);
for (int i = 0; i < n; i++) cin >> a[i].first;
a[n].first = x;
vector<pair<ll, int>> b(m);
for (int i = 0; i < m; i++) cin >> b[i].first >> b[i].second;
sort(b.begin(), b.end());
for (int i = 0; i <= n; i++) {
a[i].second = a[i].first / t;
a[i].first = lower_bound(b.begin(), b.end(), make_pair(a[i].first % t, -1)) - b.begin() - 1;
}
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end(), [](const pair<ll, ll> &l, const pair<ll, ll> &r) -> bool {
// refilling stations do the same role -> minimize their start(a.second)
return l.first == r.first;
}), a.end());
int ptr = a.size() - 1;
ll suff = 0, dp = 0, suffC = 0;
LineContainer cht;
for (int i = m - 1; i >= 0; i--) {
while (ptr >= 0 && a[ptr].first == i) {
// refilling station -> add line
// line x = { 1 * (dp - suffC + (a[ptr].second + 0) * suff), a[ptr].second + 0 };
cht.add(-1 * a[ptr].second, -1 * (dp - (a[ptr].second + 0) * suff - suffC));
// cout << "add" << endl;
ptr--;
}
ll uses = (x - b[i].first) / t + 1;
dp += uses * w;
suff += w;
suffC += b[i].second;
if (!cht.empty()) {
ll cons = -cht.query(suff) + suffC;
// cout << i << " cons " << cons << endl;
dp = min(dp, cons);
}
// cout << i << " dp " << dp << endl;
}
// driver
dp += ((x / t) + 1) * w;
// cout << a << endl;
cout << dp << '\n';
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |