Submission #951315

#TimeUsernameProblemLanguageResultExecution timeMemory
951315Nhoksocqt1Rainforest Jumps (APIO21_jumps)C++17
100 / 100
842 ms64888 KiB
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define sz(x) int((x).size()) #define fi first #define se second typedef long long ll; typedef pair<int, int> ii; template<class X, class Y> inline bool maximize(X &x, const Y &y) {return (x < y ? x = y, 1 : 0);} template<class X, class Y> inline bool minimize(X &x, const Y &y) {return (x > y ? x = y, 1 : 0);} mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int Random(int l, int r) { return uniform_int_distribution<int>(l, r)(rng); } const int MAXN = 200005; int seg[4 * MAXN]; int P[MAXN][18], Pn[MAXN][18], Pi[MAXN][18], Pa[MAXN][18]; int h[MAXN], dist[MAXN], nxt[MAXN], prv[MAXN], nTree, nArr; bool check_sub1; void build(int id, int l, int r) { if(l == r) { seg[id] = l; return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); seg[id] = (h[seg[id << 1]] > h[seg[id << 1 | 1]]) ? seg[id << 1] : seg[id << 1 | 1]; } int findLast(int id, int l, int r, int u, int v, int k) { if(u <= l && r <= v) { while(l < r) { int mid = (l + r) >> 1; if(h[seg[id << 1 | 1]] > k) { id = id << 1 | 1; l = mid + 1; } else { id = id << 1; r = mid; } } return (h[l] > k) ? l + 1 : l; } int res(0), mid = (l + r) >> 1; if(mid + 1 <= v) res = findLast(id << 1 | 1, mid + 1, r, u, v, k); if(mid >= u && (mid + 1 > v || mid + 1 == res)) res = findLast(id << 1, l, mid, u, v, k); return res; } int findFirst(int id, int l, int r, int u, int v, int k) { if(u <= l && r <= v) { while(l < r) { int mid = (l + r) >> 1; if(h[seg[id << 1]] > k) { id = id << 1; r = mid; } else { id = id << 1 | 1; l = mid + 1; } } return l; } int res(0), mid = (l + r) >> 1; if(mid >= u && h[seg[id << 1]] > k) res = findFirst(id << 1, l, mid, u, v, k); if(mid + 1 <= v && res == 0 && h[seg[id << 1 | 1]] > k) res = findFirst(id << 1 | 1, mid + 1, r, u, v, k); return res; } int query(int id, int l, int r, int u, int v) { if(u <= l && r <= v) return seg[id]; int res(0), mid = (l + r) >> 1; if(mid >= u) res = query(id << 1, l, mid, u, v); if(mid + 1 <= v) { int qr = query(id << 1 | 1, mid + 1, r, u, v); if(res == 0 || h[res] < h[qr]) res = qr; } return res; } void init(int _N, vector<int> _H) { nArr = _N; check_sub1 = 1; for (int i = 1; i <= nArr; ++i) { h[i] = _H[i - 1]; check_sub1 &= (i == 1 || h[i] > h[i - 1]); } stack<int> st; for (int i = 1; i <= nArr; ++i) { while(sz(st) && h[st.top()] <= h[i]) st.pop(); prv[i] = (sz(st)) ? st.top() : 0; st.push(i); } while(sz(st)) st.pop(); for (int i = nArr; i > 0; --i) { while(sz(st) && h[st.top()] <= h[i]) st.pop(); nxt[i] = (sz(st)) ? st.top() : nArr + 1; st.push(i); } build(1, 1, nArr); for (int i = 1; i <= nArr; ++i) { Pi[i][0] = Pa[i][0] = h[i]; P[i][0] = (h[nxt[i]] >= h[prv[i]]) ? nxt[i] : prv[i]; Pn[i][0] = nxt[i]; } P[0][0] = 0, P[nArr + 1][0] = Pn[nArr + 1][0] = nArr + 1; for (int j = 1; (1 << j) <= nArr; ++j) { for (int i = 0; i <= nArr + 1; ++i) { P[i][j] = P[P[i][j - 1]][j - 1]; Pn[i][j] = Pn[Pn[i][j - 1]][j - 1]; if(i + (1 << j) - 1 <= nArr) { Pi[i][j] = min(Pi[i][j - 1], Pi[i + (1 << (j - 1))][j - 1]); Pa[i][j] = max(Pa[i][j - 1], Pa[i + (1 << (j - 1))][j - 1]); } } } } int brute(int a, int b, int c, int d) { for (int i = 1; i <= nArr; ++i) dist[i] = -1; queue<int> qu; for (int i = a; i <= b; ++i) { qu.push(i); dist[i] = 0; } while(sz(qu)) { int u(qu.front()); qu.pop(); if(u >= c && u <= d) return dist[u]; if(prv[u] > 0 && dist[prv[u]] < 0) { dist[prv[u]] = dist[u] + 1; qu.push(prv[u]); } if(nxt[u] <= nArr && dist[nxt[u]] < 0) { dist[nxt[u]] = dist[u] + 1; qu.push(nxt[u]); } } return -1; } inline int getMin(int l, int r) { int log = 31 - __builtin_clz(r - l + 1); return min(Pi[l][log], Pi[r - (1 << log) + 1][log]); } inline int getMax(int l, int r) { int log = 31 - __builtin_clz(r - l + 1); return max(Pa[l][log], Pa[r - (1 << log) + 1][log]); } int sub5(int a, int c) { int res(0); for (int i = 31 - __builtin_clz(nArr); i >= 0; --i) { if(P[a][i] != 0 && P[a][i] != nArr + 1 && h[P[a][i]] < h[c]) { res += (1 << i); a = P[a][i]; } } for (int i = 31 - __builtin_clz(nArr); i >= 0; --i) { if(Pn[a][i] != nArr + 1 && h[Pn[a][i]] <= h[c]) { res += (1 << i); a = Pn[a][i]; } } assert(a == c); return res; } int magicFunc(int a, int b, int c, int d) { int maxBetween(-1), maxEnd = getMax(c, d); if(b + 1 <= c - 1) maxBetween = getMax(b + 1, c - 1); int e = findLast(1, 1, nArr, a, b, maxEnd - 1); //int v = findFirst(1, 1, nArr, c, d, maxBetween); int u = query(1, 1, nArr, e, b); /*cout << "\nH in [a, b] = "; for (int i = a; i <= b; ++i) cout << h[i] << ' '; cout << '\n'; cout << "H in [c, d] = "; for (int i = c; i <= d; ++i) cout << h[i] << ' '; cout << '\n'; cout << maxBetween << ' ' << maxEnd << ' ' << e << ' ' << u << ' ' << h[u] << ' ';*/ int res(0); for (int i = 31 - __builtin_clz(nArr); i >= 0; --i) { if(P[u][i] != 0 && P[u][i] != nArr + 1 && nxt[P[u][i]] < c) { u = P[u][i]; res += (1 << i); } } if(nxt[u] < c && P[u][0] > 0 && nxt[P[u][0]] <= d) { u = P[u][0]; ++res; } for (int i = 31 - __builtin_clz(nArr); i >= 0; --i) { if(Pn[u][i] != nArr + 1 && Pn[u][i] < c) { res += (1 << i); u = Pn[u][i]; } } if(u < c) { u = nxt[u]; ++res; } return res; } int minimum_jumps(int a, int b, int c, int d) { ++a, ++b, ++c, ++d; if(check_sub1) return c - b; int minStart = getMin(a, b), maxBetween(-1), maxEnd = getMax(c, d); if(b + 1 <= c - 1) maxBetween = getMax(b + 1, c - 1); if(minStart >= maxEnd || maxBetween >= maxEnd || h[b] >= maxEnd) return -1; if(a == b && c == d) return sub5(a, c); //if(brute(a, b, c, d) != magicFunc(a, b, c, d)) exit(1); //cout << brute(a, b, c, d) << ' '; return magicFunc(a, b, c, d); } #ifdef Nhoksocqt1 int main(void) { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); #define TASK "jumps" if(fopen(TASK".inp", "r")) { freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); } vector<int> h; int n, q; cin >> n >> q; h.resize(n); for (int i = 0; i < n; ++i) { cin >> h[i]; h[i] = Random(1, n); cout << h[i] << " \n"[i + 1 == n]; } init(n, h); for (int t = 0; t < q; ++t) { int a, b, c, d; cin >> a >> b >> c >> d; //a = Random(0, n - 2), b = Random(a, n - 2), c = Random(b + 1, n - 1), d = Random(c, n - 1); cout << "ANSWER " << a << ' ' << b << ' ' << c << ' ' << d << ": " << minimum_jumps(a, b, c, d) << '\n'; } return 0; } #endif // Nhoksocqt1

Compilation message (stderr)

jumps.cpp: In function 'int magicFunc(int, int, int, int)':
jumps.cpp:219:9: warning: variable 'maxBetween' set but not used [-Wunused-but-set-variable]
  219 |     int maxBetween(-1), maxEnd = getMax(c, d);
      |         ^~~~~~~~~~
#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...