Submission #426328

#TimeUsernameProblemLanguageResultExecution timeMemory
426328timmyfengShortcut (IOI16_shortcut)C++17
0 / 100
1 ms332 KiB
#include <bits/stdc++.h> using namespace std; const int N = 1000001; long long fenw[N][2], sum[N], diff[N], x[N]; int sum_order[N], diff_order[N], n; array<long long, 2> query(int a) { long long min_ans = LLONG_MAX, max_ans = LLONG_MIN; for ( ; a > 0; a -= a & -a) { min_ans = min(min_ans, fenw[a][0]); max_ans = max(max_ans, fenw[a][1]); } return {min_ans, max_ans}; } void update(int a, long long x, long long y) { for ( ; a <= n; a += a & -a) { fenw[a][0] = min(fenw[a][0], x); fenw[a][1] = max(fenw[a][1], y); } } long long find_shortcut(int n, vector<int> l, vector<int> d, int c) { // for all (i, j) where i < j: if (x_j + d_j) - (x_i - d_i) > k, // -k + c + (x_j + d_j) + (x_i + d_i) <= s + t <= k - c + (x_j - d_j) + (x_i - d_i) // -k + c + (x_j + d_j) - (x_i - d_i) <= t - s <= k - c + (x_j - d_j) - (x_i + d_i) // for each j, find the max{x_i + d_i} and the min{x_i - d_i} ::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]; } iota(sum_order, sum_order + n, 0); sort(sum_order, sum_order + n, [&](int a, int b) { return sum[a] < sum[b]; }); iota(diff_order, diff_order + n, 0); sort(diff_order, diff_order + n, [&](int a, int b) { return diff[a] < diff[b]; }); long long low = 0, high = sum[sum_order[n - 1]] - diff[diff_order[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; /* for (int i = 0; i < n; ++i) { fenw[i][0] = LLONG_MAX; fenw[i][1] = LLONG_MIN; } for (int i = 0, j = 0; j < n; ++j) { while (i < n && sum[sum_order[j]] - diff[diff_order[i]] > mid) { update(diff_order[i] + 1, diff[diff_order[i]], sum[diff_order[i]]); ++i; } auto [min_i, max_i] = query(sum_order[j]); if (min_i < LLONG_MAX) { min_sum = max(min_sum, -mid + c + sum[sum_order[j]] + max_i); max_sum = min(max_sum, mid - c + diff[sum_order[j]] + min_i); min_diff = max(min_diff, -mid + c + sum[sum_order[j]] - min_i); max_diff = min(max_diff, mid - c + diff[sum_order[j]] - max_i); } } */ for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (sum[j] - diff[i] > mid) { min_sum = max(min_sum, -mid + c + sum[j] + sum[i]); max_sum = min(max_sum, mid - c + diff[j] + diff[i]); min_diff = max(min_diff, -mid + c + sum[j] - diff[i]); max_diff = min(max_diff, mid - c + diff[j] - sum[i]); } } } 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...