Submission #168790

#TimeUsernameProblemLanguageResultExecution timeMemory
168790popovicirobertShortcut (IOI16_shortcut)C++14
97 / 100
2064 ms39544 KiB
#include "shortcut.h" #include <bits/stdc++.h> #define ll long long using namespace std; const int MAXN = (int) 1e6; int dif_ord[MAXN], sum_ord[MAXN]; ll x[MAXN + 1], d[MAXN + 1]; inline bool check(ll k, int n, int c) { vector <int> sgn = {1, -1}; int pos[2][2][2][2]; ll vals[2][2][2][2]; memset(pos, 0, sizeof(pos)); for(int conf = 0; conf < 8; conf++) { vals[conf >> 2][(conf >> 1) & 1][0][conf & 1] = -1e18; vals[conf >> 2][(conf >> 1) & 1][1][conf & 1] = 1e18; } auto upd = [&](int p, int conf) { int a = (conf >> 2), b = (conf >> 1) % 2, c = conf % 2; ll v = x[p] * sgn[a] + d[p] * sgn[b]; if(c == 0) { // mx if(vals[a][b][c][0] < v) { pos[a][b][c][1] = pos[a][b][c][0]; vals[a][b][c][1] = vals[a][b][c][0]; pos[a][b][c][0] = p; vals[a][b][c][0] = v; } else if(vals[a][b][c][1] < v) { pos[a][b][c][1] = p; vals[a][b][c][1] = v; } } else { // mn if(vals[a][b][c][0] > v) { pos[a][b][c][1] = pos[a][b][c][0]; vals[a][b][c][1] = vals[a][b][c][0]; pos[a][b][c][0] = p; vals[a][b][c][0] = v; } else if(vals[a][b][c][1] > v) { pos[a][b][c][1] = p; vals[a][b][c][1] = v; } } }; int i = 0; ll A = -1e18, B = 1e18, a = -1e18, b = 1e18; auto get = [&](int a, int b, int c, int p) { if(pos[a][b][c][0] == p) { return vals[a][b][c][1]; } return vals[a][b][c][0]; }; for(auto j : sum_ord) { if(j == 0) break; while(i < n && x[dif_ord[i]] - d[dif_ord[i]] < x[j] + d[j] - k) { upd(dif_ord[i], 3); upd(dif_ord[i], 0); i++; } B = min(B, (k - c) + x[j] - d[j] + get(0, 1, 1, j)); A = max(A, x[j] + d[j] - (k - c) + get(0, 0, 0, j)); b = min(b, (k - c) + x[j] - d[j] - get(0, 0, 0, j)); a = max(a, x[j] + d[j] - (k - c) - get(0, 1, 1, j)); } //cerr << k << " " << a << " " << b << " " << A << " " << B << "\n"; // A <= y + z <= B // a <= z - y <= b if(A > B || a > b) { return 0; } int pa = 1, pb = 1; int pc = n, pd = n; for(i = 1; i <= n; i++) { while(pd > 0 && x[i] + x[pd] > B) { pd--; } pc = min(pc, n); while(pc > 0 && x[i] + x[pc] >= A) { pc--; } pc++; pa = max(pa, 1); while(pa <= n && x[i] - x[pa] >= a) { pa++; } pa--; while(pb <= n && x[i] - x[pb] > b) { pb++; } if(max(pc, pb) <= min(pa, pd) && max(pc, pb) <= i) { return 1; } } return 0; } long long find_shortcut(int n, vector<int> l, vector<int> D, int c) { int i; for(i = 2; i <= n; i++) { x[i] = x[i - 1] + l[i - 2]; } for(i = n; i >= 1; i--) { d[i] = D[i - 1]; } iota(dif_ord, dif_ord + n, 1); iota(sum_ord, sum_ord + n, 1); sort(dif_ord, dif_ord + n, [&](const int &a, const int &b) { return x[a] - d[a] < x[b] - d[b]; }); sort(sum_ord, sum_ord + n, [&](const int &a, const int &b) { return x[a] + d[a] < x[b] + d[b]; }); ll res = 0; for(ll step = 1LL << 50; step; step >>= 1) { if(check(res + step, n, c) == 0) { res += step; } } return res + 1; }
#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...