Submission #760580

#TimeUsernameProblemLanguageResultExecution timeMemory
760580KihihihiRainforest Jumps (APIO21_jumps)C++17
100 / 100
1199 ms66864 KiB
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <iomanip> #include <algorithm> #include <numeric> #include <cmath> #include <cassert> #include <ctime> #include <chrono> #include <cstdio> #include <random> #include <vector> #include <string> #include <map> #include <unordered_map> #include <set> #include <unordered_set> #include <deque> #include <queue> #include <bitset> #include <list> #include <fstream> #include <functional> #include <complex> #include "jumps.h" using namespace std; mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count()); const int INF = 1e9, MOD = 1e9 + 7, MOD2 = 998244353, LOG = 20; const long double EPS = 1e-9, PI = acos(-1); struct sparse_table { int n; vector<int> h, lg2; vector<vector<int>> t; sparse_table() {} sparse_table(vector<int>& in) { n = in.size(); h = in; lg2.resize(n + 1); for (int i = 2; i < n + 1; i++) { lg2[i] = lg2[i / 2] + 1; } t.resize(lg2[n] + 1); t[0].resize(n); iota(t[0].begin(), t[0].end(), 0); for (int i = 1; i < t.size(); i++) { int len = (1ll << i); t[i].resize(n - len + 1); for (int j = 0; j < t[i].size(); j++) { if (h[t[i - 1][j]] > h[t[i - 1][j + len / 2]]) { t[i][j] = t[i - 1][j]; } else { t[i][j] = t[i - 1][j + len / 2]; } } } } int get(int l, int r) { int lg = lg2[r - l + 1]; if (h[t[lg][l]] > h[t[lg][r - (1ll << lg) + 1]]) { return t[lg][l]; } else { return t[lg][r - (1ll << lg) + 1]; } } }; sparse_table sptb; vector<int> v, gtl, gtr; vector<vector<int>> bingt, binls; void init(int n, std::vector<int> h) { v = h; sptb = sparse_table(h); gtl.resize(n, -1); vector<int> st; for (int i = 0; i < n; i++) { while (st.size() && v[st.back()] <= v[i]) { st.pop_back(); } if (st.size()) { gtl[i] = st.back(); } st.push_back(i); } gtr.resize(n, n); st = {}; for (int i = n - 1; i > -1; i--) { while (st.size() && v[st.back()] <= v[i]) { st.pop_back(); } if (st.size()) { gtr[i] = st.back(); } st.push_back(i); } bingt.resize(n, vector<int>(LOG, -1)); binls.resize(n, vector<int>(LOG, -1)); for (int i = 0; i < n; i++) { if (gtl[i] == -1 && gtr[i] == n) { continue; } if (gtl[i] == -1) { bingt[i][0] = binls[i][0] = gtr[i]; } if (gtr[i] == n) { bingt[i][0] = binls[i][0] = gtl[i]; } if (gtl[i] != -1 && gtr[i] != n) { if (v[gtl[i]] > v[gtr[i]]) { bingt[i][0] = gtl[i]; binls[i][0] = gtr[i]; } else { bingt[i][0] = gtr[i]; binls[i][0] = gtl[i]; } } } for (int i = 1; i < LOG; i++) { for (int j = 0; j < n; j++) { if (binls[j][i - 1] != -1) { binls[j][i] = binls[binls[j][i - 1]][i - 1]; } if (bingt[j][i - 1] != -1) { bingt[j][i] = bingt[bingt[j][i - 1]][i - 1]; } } } } int minimum_jumps(int a, int b, int c, int d) { int mxto = sptb.get(c, d); int bsl = a - 1, bsr = b + 1; while (bsr - bsl > 1) { int mid = (bsl + bsr) / 2; if (v[sptb.get(mid, b)] < v[mxto]) { bsr = mid; } else { bsl = mid; } } if (bsr == b + 1) { return -1; } a = bsr; if (b < c - 1) { if (v[sptb.get(b + 1, c - 1)] > v[mxto]) { return -1; } } d = mxto; if (b == c - 1) { return 1; } int fr = sptb.get(a, b); int btw = sptb.get(b + 1, c - 1); if (v[fr] > v[btw]) { return 1; } int ans = 0; for (int i = LOG - 1; i > -1; i--) { if (bingt[fr][i] == -1 || v[bingt[fr][i]] >= v[btw]) { continue; } ans += (1ll << i); fr = bingt[fr][i]; } if (bingt[fr][0] != -1 && v[bingt[fr][0]] < v[mxto]) { return ans + 2; } for (int i = LOG - 1; i > -1; i--) { if (binls[fr][i] == -1 || v[binls[fr][i]] > v[btw]) { continue; } ans += (1ll << i); fr = binls[fr][i]; } return ans + 1; } /* int fuck(int a, int b, int c, int d) { int n = v.size(); vector<int> dist(n, INF); deque<int> q; for (int i = a; i < b + 1; i++) { dist[i] = 0; q.push_back(i); } while (q.size()) { long long ver = q.front(); q.pop_front(); if (gtl[ver] != -1) { if (dist[gtl[ver]] > dist[ver] + 1) { dist[gtl[ver]] = dist[ver] + 1; q.push_back(gtl[ver]); } } if (gtr[ver] != n) { if (dist[gtr[ver]] > dist[ver] + 1) { dist[gtr[ver]] = dist[ver] + 1; q.push_back(gtr[ver]); } } } int ans = INF; for (int i = c; i < d + 1; i++) { ans = min(ans, dist[i]); } if (ans == INF) { return -1; } return ans; } int main() { while (true) { int N = 100; std::vector<int> H(N); iota(H.begin(), H.end(), 1); shuffle(H.begin(), H.end(), rnd); init(N, H); vector<int> prr(N); iota(prr.begin(), prr.end(), 0); shuffle(prr.begin(), prr.end(), rnd); vector<int> idk = { prr[0], prr[1], prr[2], prr[3] }; sort(idk.begin(), idk.end()); if (minimum_jumps(idk[0], idk[1], idk[2], idk[3]) != fuck(idk[0], idk[1], idk[2], idk[3])) { cout << "PSODVNOSNDV\n"; return 0; } cout << "OK\n"; sptb = {}; v = gtl = gtr = {}; bingt = binls = {}; } return 0; int N = 0, Q = 0; assert(2 == scanf("%d %d", &N, &Q)); std::vector<int> H(N); for (int i = 0; i < N; ++i) { assert(1 == scanf("%d", &H[i])); } init(N, H); for (int i = 0; i < Q; ++i) { int A = 0, B = 0, C = 0, D = 0; assert(4 == scanf("%d %d %d %d", &A, &B, &C, &D)); printf("%d\n", minimum_jumps(A, B, C, D)); } return 0; } */ /* <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠤⠖⠚⢉⣩⣭⡭⠛⠓⠲⠦⣄⡀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⢀⡴⠋⠁⠀⠀⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠳⢦⡀⠀⠀⠀⠀ ⠀⠀⠀⠀⢀⡴⠃⢀⡴⢳⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣆⠀⠀⠀ ⠀⠀⠀⠀⡾⠁⣠⠋⠀⠈⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢧⠀⠀ ⠀⠀⠀⣸⠁⢰⠃⠀⠀⠀⠈⢣⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣇⠀ ⠀⠀⠀⡇⠀⡾⡀⠀⠀⠀⠀⣀⣹⣆⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀ ⠀⠀⢸⠃⢀⣇⡈⠀⠀⠀⠀⠀⠀⢀⡑⢄⡀⢀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇ ⠀⠀⢸⠀⢻⡟⡻⢶⡆⠀⠀⠀⠀⡼⠟⡳⢿⣦⡑⢄⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇ ⠀⠀⣸⠀⢸⠃⡇⢀⠇⠀⠀⠀⠀⠀⡼⠀⠀⠈⣿⡗⠂⠀⠀⠀⠀⠀⠀⠀⢸⠁ ⠀⠀⡏⠀⣼⠀⢳⠊⠀⠀⠀⠀⠀⠀⠱⣀⣀⠔⣸⠁⠀⠀⠀⠀⠀⠀⠀⢠⡟⠀ ⠀⠀⡇⢀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀ ⠀⢸⠃⠘⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠁⠀⠀⢀⠀⠀⠀⠀⠀⣾⠀⠀ ⠀⣸⠀⠀⠹⡄⠀⠀⠈⠁⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠸⠀⠀⠀⠀⠀⡇⠀⠀ ⠀⡏⠀⠀⠀⠙⣆⠀⠀⠀⠀⠀⠀⠀⢀⣠⢶⡇⠀⠀⢰⡀⠀⠀⠀⠀⠀⡇⠀⠀ ⢰⠇⡄⠀⠀⠀⡿⢣⣀⣀⣀⡤⠴⡞⠉⠀⢸⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⣧⠀⠀ ⣸⠀⡇⠀⠀⠀⠀⠀⠀⠉⠀⠀⠀⢹⠀⠀⢸⠀⠀⢀⣿⠇⠀⠀⠀⠁⠀⢸⠀⠀ ⣿⠀⡇⠀⠀⠀⠀⠀⢀⡤⠤⠶⠶⠾⠤⠄⢸⠀⡀⠸⣿⣀⠀⠀⠀⠀⠀⠈⣇⠀ ⡇⠀⡇⠀⠀⡀⠀⡴⠋⠀⠀⠀⠀⠀⠀⠀⠸⡌⣵⡀⢳⡇⠀⠀⠀⠀⠀⠀⢹⡀ ⡇⠀⠇⠀⠀⡇⡸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠮⢧⣀⣻⢂⠀⠀⠀⠀⠀⠀⢧ ⣇⠀⢠⠀⠀⢳⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡎⣆⠀⠀⠀⠀⠀⠘ ⢻⠀⠈⠰⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠘⢮⣧⡀⠀⠀⠀⠀ ⠸⡆⠀⠀⠇⣾⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠆⠀⠀⠀⠀⠀⠀⠀⠙⠳⣄⡀⢢⡀ <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 */

Compilation message (stderr)

jumps.cpp: In constructor 'sparse_table::sparse_table(std::vector<int>&)':
jumps.cpp:53:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   53 |         for (int i = 1; i < t.size(); i++)
      |                         ~~^~~~~~~~~~
jumps.cpp:57:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   57 |             for (int j = 0; j < t[i].size(); j++)
      |                             ~~^~~~~~~~~~~~~
#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...