Submission #1302070

#TimeUsernameProblemLanguageResultExecution timeMemory
1302070uranium235Long Distance Coach (JOI17_coach)C++17
100 / 100
132 ms19180 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...