Submission #789417

#TimeUsernameProblemLanguageResultExecution timeMemory
789417fatemetmhrShortcut (IOI16_shortcut)C++17
97 / 100
2088 ms458772 KiB
// ~ Be Name Khoda ~ // //#pragma GCC optimize ("O3") #pragma GCC target("avx,abm,bmi,bmi2") #pragma GCC optimize("unroll-loops,Ofast") #include <bits/stdc++.h> #include <vector> long long find_shortcut(int n, std::vector <int> l, std::vector <int> d, int c); using namespace std; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); typedef long long ll; #define pb push_back #define mp make_pair #define all(x) x.begin(), x.end() #define fi first #define se second const int maxn = 1e6 + 10; const int maxn5 = 1e6 + 10; const int maxnl = 1e7 + 10; const int maxn3 = 1e3 + 10; const ll mod = 1e9 + 7; const int lg = 22; const ll inf = 1e18; int n, ind[maxn5]; ll c; vector <ll> d; ll ps[maxn5]; pair <pair<ll, int>, pair<ll, ll>> av[maxn5]; pair <ll, ll> mxx[lg][maxn5]; vector <pair<ll, int>> srt; // c + d[i] + ps[i] - ps[a] + cons - ps[b] <= lim // d[i] + ps[i] + cons <= lim - c + ps[b] + ps[a] pair <ll, ll> comb(const pair <ll, ll> &a, const pair <ll, ll> &b){ return {a.fi > b.fi? a.fi: b.fi, a.se > b.se? a.se: b.se}; } struct RMQ{ ll mx[maxn5]; bool ty; void build(int n){ if(ty) for(int i = 1; i < n; i++) mx[i] = max(mx[i], mx[i - 1]); else for(int i = n - 2; i >= 0; i--) mx[i] = max(mx[i], mx[i + 1]); } } rmq[2][2]; pair <ll, ll> get_max(int l, int r){ if(l > r) return {-inf, -inf}; if(r == n - 1) return av[l].se; int k = 31 - __builtin_clz(r - l + 1); return comb(mxx[k][l], mxx[k][r - (1 << k) + 1]); } // (ty ? 1 : -1) * ps[b] <= lim - c + ps[a] - rmq[0][ty].mx[a] // (ty ? 1 : -1) * ps[b] <= lim - c - ps[a] - rmq[1][ty].mx[a] bool check2(int a, int b, int ty, ll lim){ //cout << "for " << a << ' ' << b << ' ' << ty << ' ' << lim << endl; //cout << rmq[0][ty].get_max(a, n - 1) << ' ' << lim - c + (ty ? -1 : 1) * ps[b] - ps[a] << endl; if(rmq[0][ty].mx[a] > lim - c + (ty ? -1 : 1) * ps[b] + ps[a]) return false; if(rmq[1][ty].mx[a] > lim - c + (ty ? -1 : 1) * ps[b] - ps[a]) return false; //cout << "result in true " << endl; return true; } bool check(ll lim){ //cout << "************** in lim " << lim << endl; int pt = 0; for(auto [w, i] : srt){ while(pt < n && lim - w >= av[pt].fi.fi) pt++; if(i == n){ for(int x = 0; x < 2; x++) for(int y = 0; y < 2; y++) rmq[x][y].mx[i] = -inf; continue; } pair <ll, ll> ans = {-inf, -inf}; if(ind[i] < pt) ans = get_max(pt, n - 1); else ans = comb(get_max(pt, ind[i] - 1), get_max(ind[i] + 1, n - 1)); //cout << "in " << i << ' ' << pt << ' ' << av.size() << endl; ll cons[2] = {ans.fi, ans.se}; //cout << i << ' ' << cons[0] << ' ' << cons[1] << endl; for(int x = 0; x < 2; x++) for(int y = 0; y < 2; y++) rmq[x][y].mx[i] = d[i] + cons[y] + ps[i] * (x ? -1 : 1); } rmq[0][0].ty = 0; rmq[0][1].ty = 0; rmq[1][0].ty = 1; rmq[1][1].ty = 1; rmq[0][0].build(n); // 0 is suf rmq[0][1].build(n); rmq[1][0].build(n); rmq[1][1].build(n); int b[2][2]; b[0][0] = n; b[0][1] = 0; b[1][0] = 0; b[1][1] = n - 1; for(int i = 0; i < n; i++){ while(b[0][0] - 1 >= 0 && -ps[b[0][0] - 1] <= lim - c + ps[i] - rmq[0][0].mx[i]) b[0][0]--; while(b[1][1] >= 0 && ps[b[1][1]] > lim - c - ps[i] - rmq[1][1].mx[i]) b[1][1]--; while(b[0][1] + 1 < n && ps[b[0][1] + 1] <= lim - c + ps[i] - rmq[0][1].mx[i]) b[0][1]++; while(b[1][0] < n && -ps[b[1][0]] > lim - c - ps[i] - rmq[1][0].mx[i]) b[1][0]++; int l = max({i + 1, b[0][0], b[1][0]}); int r = min(b[0][1], b[1][1]); /* int lo = i, hi = n; while(hi - lo > 1){ int mid = (lo + hi) >> 1; if(check2(i, mid, 0, lim)) hi = mid; else lo = mid; } int l = max(i + 1, hi); lo = i; hi = n; while(hi - lo > 1){ int mid = (lo + hi) >> 1; if(check2(i, mid, 1, lim)) lo = mid; else hi = mid; } int r = min(n, lo); */ //cout << "ok " << i << ' ' << l << ' ' << r << endl; if(l <= r) return true; } return false; /* for(int i = 0; i < n; i++) if(pt[i] < av[i].size()){ int b = 0; for(auto [w, a] : srt[i]){ while(b + 1 < n && c + d[i] + w + av[i][pt[i]].se.fi - ps[b] > lim) b++; l[a] = max(l[a], b); } b = n - 1; for(auto [w, a] : srt[i]){ while(b && c + d[i] + w + av[i][pt[i]].se.se + ps[b] > lim) b--; r[a] = min(r[a], b); } /* int lo = i, hi = n; while(hi - lo > 1){ int mid = (lo + hi) >> 1; if(check(i, mid, 0, lim)) hi = mid; else lo = mid; } l = max(i + 1, hi); lo = i; hi = n; while(hi - lo > 1){ int mid = (lo + hi) >> 1; if(check(i, mid, 1, lim)) lo = mid; else hi = mid; } r = min(n, lo); //////cout << "ok " << lim << ' ' << i << ' ' << l << ' ' << r << endl; if(l <= r) return true; /* bool re = true; for(int j = 0; j < n && re; j++) for(int k = j + 1; k < n && re; k++) if(dis(j, k) + d[j] + d[k] > lim){ ll dis1 = dis(i, j); ll need = lim - c - d[j] - d[k] - dis1; if(need < 0) re = false; int ptl = k - (upper_bound(all(av[k][0]), need) - av[k][0].begin() - 1); int ptr = k + (upper_bound(all(av[k][1]), need) - av[k][1].begin() - 1); l = max(l, ptl); r = min(r, ptr); //////cout << lim << ' ' << i << ' ' << j << ' ' << k << ' ' << l << ' ' << r << endl; if(l > r) re = false; } if(re) return true; } */ } long long find_shortcut(int N, std::vector<int> l, std::vector<int> D, int C) { n = N; c = C; for(auto u : D) d.pb(u); ps[0] = 0; for(int i = 0; i < n; i++){ if(i) ps[i] = ps[i - 1] + l[i - 1]; av[i] = {{d[i] + ps[i], i}, {d[i] + ps[i], d[i] - ps[i]}}; srt.pb({d[i] - ps[i], i}); } sort(all(srt)); reverse(all(srt)); sort(av, av + n); for(int i = n - 1; i >= 0; i--){ ind[av[i].fi.se] = i; mxx[0][i] = av[i].se; if(i != n - 1) av[i].se = comb(av[i].se, av[i + 1].se); } for(int i = 1; i < lg; i++) for(int j = 0; j < n; j++) mxx[i][j] = comb(mxx[i - 1][j], j + (1 << (i - 1)) < n ? mxx[i - 1][j + (1 << (i - 1))] : mp(-inf, -inf)); /* for(int i = 0; i < n; i++){ for(int j = i + 1; j < n; j++) av[i].pb({dis(i, j) + d[i] + d[j], {d[j] + ps[j], d[j] - ps[j]}}); //if(i == 1) // ////cout << av[i][1].back().se << ' ' << av[i][1].back().fi << endl; sort(all(av[i])); for(int j = int(av[i].size()) - 2; j >= 0; j--){ //if(i == 1) // ////cout << j << endl; av[i][j].se.fi = max(av[i][j].se.fi, av[i][j + 1].se.fi); av[i][j].se.se = max(av[i][j].se.se, av[i][j + 1].se.se); } //if(i == 1) // ////cout << av[i][1].back().se << ' ' << av[i][1].back().fi << endl; } */ ll lo = -1, hi = mod * (n + 3); while(hi - lo > 1){ ll mid = (lo + hi) >> 1; if(check(mid)) hi = mid; else lo = mid; } return hi; }

Compilation message (stderr)

shortcut.cpp:184:9: warning: "/*" within comment [-Wcomment]
  184 |         /*
      |          
shortcut.cpp:210:9: warning: "/*" within comment [-Wcomment]
  210 |         /*
      |
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...