Submission #69841

#TimeUsernameProblemLanguageResultExecution timeMemory
69841BenqLong Distance Coach (JOI17_coach)C++14
100 / 100
330 ms167588 KiB
#pragma GCC optimize ("O3") #pragma GCC target ("sse4") #include <bits/stdc++.h> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/rope> using namespace std; using namespace __gnu_pbds; using namespace __gnu_cxx; typedef long long ll; typedef long double ld; typedef complex<ld> cd; typedef pair<int, int> pi; typedef pair<ll,ll> pl; typedef pair<ld,ld> pd; typedef vector<int> vi; typedef vector<ld> vd; typedef vector<ll> vl; typedef vector<pi> vpi; typedef vector<pl> vpl; typedef vector<cd> vcd; template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; #define FOR(i, a, b) for (int i=a; i<(b); i++) #define F0R(i, a) for (int i=0; i<(a); i++) #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--) #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--) #define sz(x) (int)(x).size() #define mp make_pair #define pb push_back #define f first #define s second #define lb lower_bound #define ub upper_bound #define all(x) x.begin(), x.end() const int MOD = 1000000007; const ll INF = 4e18; const int MX = 200005; bool Q; struct Line { mutable ll k, m, p; // slope, y-intercept, last optimal x bool operator<(const Line& o) const { return Q ? p < o.p : k < o.k; } }; struct LineContainer : multiset<Line> { const ll inf = LLONG_MAX; ll div(ll a, ll b) { // floored division if (b < 0) a *= -1, b *= -1; if (a >= 0) return a/b; return -((-a+b-1)/b); } // updates x->p, determines if y is unneeded bool isect(iterator x, iterator y) { if (y == end()) { x->p = inf; return 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) { k *= -1, m *= -1; 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) { // gives max value if (empty()) return INF; Q = 1; auto l = *lb({0,0,x}); Q = 0; return -(l.k * x + l.m); } }; LineContainer L; ll X,N,M,W,T, cum[MX], dp[MX]; vpl D, S; void mn(ll& a, ll b) { a = min(a,b); } void input() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> X >> N >> M >> W >> T; S.resize(N+1); F0R(i,N) cin >> S[i].s; S[N].s = X; F0R(i,N+1) S[i].f = S[i].s % T; D.resize(M+1); F0R(i,M) cin >> D[i].f >> D[i].s; D[M] = {T,0}; sort(all(S)), sort(all(D)); F0R(i,M+1) { if (i) cum[i] = cum[i-1]; cum[i] += D[i].s; } } int main() { input(); int ind = N+1; dp[M] = (X/T+1)*W; F0Rd(i,M) { ll val = min(L.query(i)-cum[i],dp[i+1]); ll bes = INF; while (ind && S[ind-1].f >= D[i].f) mn(bes,S[--ind].s/T*W); if (bes != INF) L.add(-bes,val+bes*i+cum[i]); dp[i] = val+((X-D[i].f)/T+1)*W; } ll val = min(L.query(-1),dp[0]); cout << val; } /* Look for: * the exact constraints (multiple sets are too slow for n=10^6 :( ) * special cases (n=1?) * overflow (ll vs int?) * array bounds * if you have no idea just guess the appropriate well-known algo instead of doing nothing :/ */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...