Submission #426396

#TimeUsernameProblemLanguageResultExecution timeMemory
426396timmyfengShortcut (IOI16_shortcut)C++17
97 / 100
2008 ms94012 KiB
#include <bits/stdc++.h> using namespace std; const int N = 1000001; long long sum_s[N], diff_s[N], sum_d[N], diff_d[N]; long long sum[N], diff[N], x[N]; int order[N], n; long long find_shortcut(int n, vector<int> l, vector<int> d, int c) { ::n = n; for (int i = 0; i < n - 1; ++i) { x[i + 1] = x[i] + l[i]; } for (int i = 0; i < n; ++i) { sum[i] = x[i] + d[i]; diff[i] = x[i] - d[i]; } sort(d.rbegin(), d.rend()); iota(order, order + n, 0); sort(order, order + n, [&](int a, int b) { return diff[a] < diff[b]; }); for (int i = 0; i < n; ++i) { sum_d[i] = sum[order[i]]; diff_d[i] = diff[order[i]]; } iota(order, order + n, 0); sort(order, order + n, [&](int a, int b) { return sum[a] < sum[b]; }); for (int i = 0; i < n; ++i) { sum_s[i] = sum[order[i]]; diff_s[i] = diff[order[i]]; } long long low = d[0] + d[1], high = sum_s[n - 1] - diff_d[0]; while (low < high) { long long mid = (low + high) / 2; long long min_sum = LLONG_MIN, max_sum = LLONG_MAX; long long min_diff = LLONG_MIN, max_diff = LLONG_MAX; long long s = LLONG_MIN, d = LLONG_MAX; for (int i = 0, j = 0; j < n; ++j) { while (i < n && sum_s[j] - diff_d[i] > mid) { s = max(s, sum_d[i]); d = min(d, diff_d[i]); ++i; } if (sum_s[j] - diff_s[j] > mid) { int y = order[j]; for (int x = 0; x < y; ++x) { if (sum[y] - diff[x] > mid) { min_sum = max(min_sum, -mid + c + sum[y] + sum[x]); max_sum = min(max_sum, mid - c + diff[y] + diff[x]); min_diff = max(min_diff, -mid + c + sum[y] - diff[x]); max_diff = min(max_diff, mid - c + diff[y] - sum[x]); } } } else if (s > LLONG_MIN) { min_sum = max(min_sum, -mid + c + sum_s[j] + s); max_sum = min(max_sum, mid - c + diff_s[j] + d); min_diff = max(min_diff, -mid + c + sum_s[j] - d); max_diff = min(max_diff, mid - c + diff_s[j] - s); } } bool ok = false; int l1 = n - 1, l2 = 0, r1 = n - 1, r2 = 0; for (int i = 0; i < n; ++i) { while (l1 >= 0 && x[i] + x[l1] >= min_sum) { --l1; } while (r1 >= 0 && x[i] + x[r1] > max_sum) { --r1; } while (l2 < n && x[i] - x[l2] > max_diff) { ++l2; } while (r2 < n && x[i] - x[r2] >= min_diff) { ++r2; } ok |= max(l1 + 1, l2) < min(r1 + 1, r2); } if (ok) { high = mid; } else { low = mid + 1; } } return low; }
#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...