Submission #568568

#TimeUsernameProblemLanguageResultExecution timeMemory
568568hoanghq2004Shortcut (IOI16_shortcut)C++14
71 / 100
2068 ms71236 KiB
#include <bits/stdc++.h> #pragma GCC optimization ("O3") #pragma GCC optimization ("unroll-loops") #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #include "shortcut.h" using namespace __gnu_pbds; using namespace std; template <typename T> using ordered_set = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>; const int N = 1e6 + 10; long long x[N]; long long suf[N][4]; struct node { long long Max, Min; node() { Max = 1e18, Min = - 1e18; } node operator + (const node& other) const { node ret; ret.Max = min(Max, other.Max); ret.Min = max(Min, other.Min); return ret; } }; struct SegmentTree { node st[N * 4]; void add(int id, int L, int R, int i, long long Max, long long Min) { if (L == R) { st[id].Max = Max; st[id].Min = Min; return; } int mid = L + R >> 1; if (i <= mid) add(id * 2, L, mid, i, Max, Min); else add(id * 2 + 1, mid + 1, R, i, Max, Min); st[id] = st[id * 2] + st[id * 2 + 1]; } node get(int id, int L, int R, int u, int v) { if (u <= L && R <= v) return st[id]; int mid = L + R >> 1; if (v <= mid) return get(id * 2, L, mid, u, v); if (u > mid) return get(id * 2 + 1, mid + 1, R, u, v); return get(id * 2, L, mid, u, v) + get(id * 2 + 1, mid + 1, R, u, v); } } IT; long long find_shortcut(int n, vector<int> l, vector<int> d, int c) { for (int i = 0; i < n - 1; ++i) x[i + 1] = x[i] + l[i]; vector <pair <long long, int>> ord1, ord2; for (int i = 0; i < n; ++i) ord1.push_back({x[i] - d[i], i}); for (int i = 0; i < n; ++i) ord2.push_back({x[i] + d[i], i}); sort(ord1.begin(), ord1.end()); sort(ord2.begin(), ord2.end()); auto check = [&](long long len) { long long max1 = 1e18, min1 = - 1e18; long long max2 = 1e18, min2 = - 1e18; int id = 0; for (auto [delta, j]: ord2) IT.add(1, 0, n - 1, j, x[j] - d[j], x[j] + d[j]); for (auto [delta, i]: ord1) { while (id < ord2.size() && get<0>(ord2[id]) <= len + delta) { int j = get<1>(ord2[id]); IT.add(1, 0, n - 1, j, 1e18, -1e18); ++id; } if (i + 1 == n) continue; node cur = IT.get(1, 0, n - 1, i + 1, n - 1); long long r = len - d[i] - c; max1 = min(max1, x[i] + cur.Max + r); min1 = max(min1, x[i] + cur.Min - r); max2 = min(max2, - x[i] + cur.Max + r); min2 = max(min2, - x[i] + cur.Min - r); } if (max1 < min1 || max2 < min2) return 0; for (int i = 0; i < n; ++i) { long long L = max(min1 - x[i], min2 + x[i]); long long R = min(max1 - x[i], max2 + x[i]); int j = lower_bound(x, x + n, L) - x; if (j == n || x[j] > R) continue; return 1; } return 0; }; long long L = 0, R = 1e15; while (L < R) { long long mid = L + R >> 1; if (check(mid)) R = mid; else L = mid + 1; } return L; } // // //int main() //{ // int n, c; // assert(2 == scanf("%d%d", &n, &c)); // // std::vector<int> l(n - 1); // std::vector<int> d(n); // for (int i = 0; i < n - 1; i++) // assert(1 == scanf("%d", &l[i])); // for (int i = 0; i < n; i++) // assert(1 == scanf("%d", &d[i])); // // long long t = find_shortcut(n, l, d, c); // // // printf("%lld\n", t); // // return 0; //}

Compilation message (stderr)

shortcut.cpp:2: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
    2 | #pragma GCC optimization ("O3")
      | 
shortcut.cpp:3: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
    3 | #pragma GCC optimization ("unroll-loops")
      | 
shortcut.cpp: In member function 'void SegmentTree::add(int, int, int, int, long long int, long long int)':
shortcut.cpp:40:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   40 |         int mid = L + R >> 1;
      |                   ~~^~~
shortcut.cpp: In member function 'node SegmentTree::get(int, int, int, int, int)':
shortcut.cpp:47:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   47 |         int mid = L + R >> 1;
      |                   ~~^~~
shortcut.cpp: In lambda function:
shortcut.cpp:66:19: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   66 |         for (auto [delta, j]: ord2) IT.add(1, 0, n - 1, j, x[j] - d[j], x[j] + d[j]);
      |                   ^
shortcut.cpp:67:19: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   67 |         for (auto [delta, i]: ord1) {
      |                   ^
shortcut.cpp:68:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   68 |             while (id < ord2.size() && get<0>(ord2[id]) <= len + delta) {
      |                    ~~~^~~~~~~~~~~~~
shortcut.cpp: In function 'long long int find_shortcut(int, std::vector<int>, std::vector<int>, int)':
shortcut.cpp:93:27: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   93 |         long long mid = L + R >> 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...