Submission #171541

#TimeUsernameProblemLanguageResultExecution timeMemory
171541ho94949Long Distance Coach (JOI17_coach)C++17
100 / 100
853 ms39728 KiB
#include<bits/stdc++.h> using namespace std; const int MAXN = 202020; long long X, N, M, W, T; long long S[MAXN]; long long D[MAXN], C[MAXN]; // used water before kickout long long nw[MAXN]; //1~(i-1) customer minimum value when ith person do not kicked // -(C_1+...+C_i)+ WV[i] customer's required value. long long DP[MAXN]; // drank water of ith customer if none was kicked long long WV[MAXN]; int pv[MAXN]; // min li-chao tree struct Line { long long a; long long b; }; const long long INFV = (long long)1e18; Line emptyl = {INFV, INFV}; struct Node { long long s, e; Node* l; Node* r; Line v; Node(long long _s, long long _e) :s(_s), e(_e), l(nullptr), r(nullptr), v(emptyl) { } __int128 getv(long long x) { assert(v.a != INFV); __int128 ans = (__int128)v.a*x+v.b; long long m = (s+e)>>1; if(x<=m && l) ans = min(ans, l->getv(x)); if(x>m && r) ans = min(ans, r->getv(x)); return ans; } void setv(Line x) { if(v.a==INFV && v.b==INFV) { v = x; return; } if(s==e) { if((__int128)s*v.a+v.b > (__int128)s*x.a+x.b) swap(v, x); return; } long long m = (s+e)>>1; long long pt = 2*m+1; __int128 exist = (__int128)v.a*pt+2*v.b; __int128 nv = (__int128)x.a*pt+2*x.b; if(exist > nv) swap(v, x); if(v.a < x.a) { if(!l) l = new Node(s, m); l->setv(x); } else { if(!r) r = new Node(m+1, e); r->setv(x); } } }; long long do_dp() { Node* root = new Node(-INFV, INFV); DP[0] = 0; root->setv({-0, DP[0]}); for(int i=1; i<=M+1; ++i) { DP[i] = DP[i-1]; // not kicking (i-1)th customer if(nw[i] != -1) // if can start kicking strategy, { DP[i] = min(DP[i], (long long)(root->getv(nw[i])+(i-1)*nw[i])); /* for(int j=i-2; j>=0; --j) //not kicking jth customer, kicking all DP[i] = min(DP[i], DP[j]+(i-j-1)*nw[i]); */ } if(pv[i] != 0) //kick through pv player and let what they want. { //cout << "!" << i << " " << pv[i] << endl; DP[i] = min(DP[i], DP[pv[i]] - WV[pv[i]] +C[pv[i]] + (i-pv[i])*nw[i]); } DP[i] += -C[i] + WV[i]; root->setv({-i, DP[i]}); //printf("%d %lld %lld\n", i, nw[i], DP[i]); } long long ans = DP[M+1]; //basic DP value; //we remove C_1...C_M for(int i=1; i<=M; ++i) ans += C[i]; // WV[M+1] is defined as 0 // we should add bus drivers' cost ans += W*(1+X/T); return ans; } int main() { cin >> X >> N >> M >> W >> T; for(int i=0; i<N; ++i) cin >> S[i]; vector<pair<long long, long long> > VDC; for(int i=0; i<M; ++i) { long long d, c; cin >> d >> c; VDC.emplace_back(d, c); } sort(VDC.begin(), VDC.end()); for(int i=1; i<=M; ++i) { tie(D[i], C[i]) = VDC[i-1]; WV[i] = W*(1+(X-D[i])/T); //printf("%d: %lld %lld\n", i, WV[i], C[i]); } S[N] = X; sort(S, S+N+1); memset(nw, -1, sizeof nw); set<int> SS; for(int i=0; i<=N; ++i) { long long kickout_water = W*(S[i]/T); int kick_index = lower_bound(D+1, D+1+M, S[i]%T) - D; //printf("%lld %d\n", kickout_water, kick_index); // we will decide whether kick 1~kick_index if(kick_index == 1) continue; if(nw[kick_index] != -1) continue; nw[kick_index] = kickout_water; SS.insert(kick_index); auto it = SS.find(kick_index); if(it != SS.begin()) pv[kick_index] = *(--it); } printf("%lld\n", do_dp()); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...