Submission #1243536

#TimeUsernameProblemLanguageResultExecution timeMemory
1243536Hamed_GhaffariOvertaking (IOI23_overtaking)C++20
9 / 100
1 ms1604 KiB
#include "overtaking.h" #include <bits/stdc++.h> using namespace std; using ll = long long; using pll = pair<ll, ll>; #define ff first #define ss second #define mid ((l+r)>>1) const int MXN = 1003; const ll MX = 1'000'000'001'000'000'003; inline pll eval(pll f, ll x) { return pll(x+f.ff, f.ss); } inline bool cmp(pll f, pll g) { return (__int128_t)f.ff*g.ss <= (__int128_t)g.ff*f.ss; } inline pair<pll, int> min_(pair<pll, int> x, pair<pll, int> y) { return cmp(x.ff, y.ff) ? x : y; } struct lichao { lichao *lc, *rc; pll f; int id; lichao(): lc(NULL), rc(NULL), f(pll(MX, 1)), id(-1) {} lichao *cpy() { lichao *v = new lichao(); v->lc = lc, v->rc = rc, v->f = f; return v; } void del() { if(lc) lc->del(); if(rc) rc->del(); delete this; } }; lichao *add(pll f, int id, lichao *vv, bool pers, ll l=0, ll r=MX) { if(!vv) { lichao *v = new lichao(); v->f = f; v->id = id; return v; } lichao *v = pers ? vv->cpy() : vv; if(r-l == 1) { if(cmp(eval(f, l), eval(v->f, l))) { v->f = f; v->id = id; } return v; } bool L = cmp(eval(f, l), eval(v->f, l)); bool M = cmp(eval(f, mid), eval(v->f, mid)); if(M) { swap(f, v->f); swap(id, v->id); } if(L==M) v->rc = add(f, id, v->rc, pers, mid, r); else v->lc = add(f, id, v->lc, pers, l, mid); return v; } pair<pll, int> get(ll x, lichao *v, ll l=0, ll r=MX) { if(!v) return {{MX, 1}, -1}; return min_({eval(v->f, x), v->id}, x<mid ? get(x, v->lc, l, mid) : get(x, v->rc, mid, r)); } int L, n, m, X, ord[MXN]; vector<ll> T; vector<int> W, S; ll t[MXN][MXN], e[MXN][MXN], dp[MXN][MXN]; lichao *root[MXN]; void init(int L_, int N, vector<ll> T_, vector<int> W_, int X_, int M, vector<int> S_) { L = L_, n = N, T = T_, W = W_, X = X_, m = M, S = S_; int ptr=0; for(int i=0; i<n; i++) if(W[i]>X) { T[ptr] = T[i]; W[ptr++] = W[i]; } n = ptr; if(n==0) return; for(int i=0; i<n; i++) t[i][0] = T[i]; iota(ord, ord+n, 0); for(int j=0; j+1<m; j++) { sort(ord, ord+n, [&](int x, int y) { return t[x][j] < t[y][j]; }); for(int i=0; i<n; i++) e[i][j+1] = t[i][j] + 1ll*W[i]*(S[j+1]-S[j]); ll mx = 0; for(int l=0,r; l<n; ) { r=l; while(r+1<n && t[ord[r+1]][j]==t[ord[r]][j]) r++; ll mx2=mx; for(int i=l; i<=r; i++) mx2 = max(mx2, e[ord[i]][j+1]), t[ord[i]][j+1] = max(e[ord[i]][j+1], mx); mx = mx2; l=r+1; } } // for(int i=0; i<n; i++) { // cout << t[i][0] << ' '; // for(int j=1; j<m; j++) { // cout << e[i][j] << ' ' << t[i][j] << ' '; // } // cout << '\n'; // } // cout << '\n'; for(int j=m-2; j>=0; j--) { sort(ord, ord+n, [&](int x, int y) { return t[x][j] < t[y][j]; }); lichao *ds = NULL; for(int i=0; i<n; i++) { if(t[ord[i]][j]>t[ord[0]][j]) { auto x = get(t[ord[i]][j], ds); // cout << ord[i] << ' ' << j << ": " << t[ord[i]][j] << ' ' << x.ff.ff << ' ' << x.ff.ss << ' ' << x.ss << '\n'; ll up = x.ff.ff, dw = x.ff.ss; int pos = lower_bound(S.begin(), S.end(), S[j]+(up+dw-1)/dw)-S.begin(); if(pos==m) dp[ord[i]][j] = 1ll*X*(L-S[j]); else dp[ord[i]][j] = t[x.ss][pos]-t[ord[i]][j] + dp[x.ss][pos]; } else dp[ord[i]][j] = 1ll*X*(L-S[j]); ds = add({-t[ord[i]][j], W[ord[i]]-X}, ord[i], ds, 0); } ds->del(); } sort(ord, ord+n, [&](int i, int j) { return t[i][0] < t[j][0]; }); lichao *ds = NULL; for(int i=0; i<n; i++) root[i] = ds = add({-t[ord[i]][0], W[ord[i]]-X}, ord[i], ds, 1); // for(int i=0; i<n; i++) cout << T[i] << ' ' << W[i] << '\n'; // for(int i=0; i<n; i++) { // for(int j=0; j<m; j++) // cout << dp[i][j] << ' '; // cout << '\n'; // } } ll arrival_time(ll Y) { if(n==0 || t[ord[0]][0]>=Y) return Y + 1ll*X*L; int l=0, r=n; while(r-l>1) (t[ord[mid]][0]<Y ? l : r) = mid; auto x = get(Y, root[l]); ll up = x.ff.ff, dw = x.ff.ss; int pos = lower_bound(S.begin(), S.end(), (up+dw-1)/dw)-S.begin(); if(pos==m) return Y + 1ll*X*L; return t[x.ss][pos] + dp[x.ss][pos]; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...