Submission #1073108

#TimeUsernameProblemLanguageResultExecution timeMemory
1073108ZicrusRadio Towers (IOI22_towers)C++17
56 / 100
838 ms17092 KiB
#include <bits/stdc++.h> #include "towers.h" using namespace std; typedef long long ll; int n, pow2; vector<int> h; vector<int> segMn, segMx, segPeak, segVal; vector<vector<int>> jmp; bool initialized; int nxtPeak(int i, int val) { i += pow2; while (i) { if (segMx[i] >= val) break; if (i & 1) { if ((i & (i+1)) == 0) return n; i++; } i /= 2; } while (i < pow2) { if (segMx[2*i] >= val) i = 2*i; else i = 2*i+1; } return i-pow2; } int nxtVal(int i, int val) { i += pow2; while (i) { if (segMn[i] <= val) break; if (i & 1) { if ((i & (i+1)) == 0) return n; i++; } i /= 2; } while (i < pow2) { if (segMn[2*i] <= val) i = 2*i; else i = 2*i+1; } return i-pow2; } void setSegPeak(int i, int val) { i += pow2; segPeak[i] = val; i /= 2; while (i) { segPeak[i] = min(segPeak[2*i], segPeak[2*i+1]); i /= 2; } } void setSegVal(int i, int val) { i += pow2; segVal[i] = val; i /= 2; while (i) { segVal[i] = min(segVal[2*i], segVal[2*i+1]); i /= 2; } } int getSegPeak(int low, int high) { low += pow2; high += pow2; int res = n; while (low <= high) { if (low & 1) res = min(res, segPeak[low++]); if (!(high & 1)) res = min(res, segPeak[high--]); low /= 2; high /= 2; } return res; } int getSegVal(int low, int high) { low += pow2; high += pow2; int res = n; while (low <= high) { if (low & 1) res = min(res, segVal[low++]); if (!(high & 1)) res = min(res, segVal[high--]); low /= 2; high /= 2; } return res; } void init(int N, vector<int> H) { n = N; h = H; initialized = false; pow2 = 1 << (int)ceil(log2(n)); segMn = vector<int>(2*pow2); segMx = vector<int>(2*pow2); for (int i = 0; i < n; i++) { segMn[pow2+i] = h[i]; segMx[pow2+i] = h[i]; } for (int i = pow2-1; i > 0; i--) { segMn[i] = min(segMn[2*i], segMn[2*i+1]); segMx[i] = max(segMx[2*i], segMx[2*i+1]); } } void init2(int D) { initialized = true; segPeak = vector<int>(2*pow2, n); segVal = vector<int>(2*pow2, n); for (int i = n-2; i >= 0; i--) { int nxtP = nxtPeak(i+1, h[i]+D); int nxtV = nxtVal(i+1, h[i]-D); nxtP = min(nxtP, getSegPeak(i+1, nxtP-1)); nxtV = min(nxtV, getSegVal(i+1, nxtV-1)); setSegPeak(i, nxtP); setSegVal(i, nxtV); } jmp = vector<vector<int>>(n, vector<int>(20, n)); for (int i = 0; i < n; i++) { jmp[i][0] = segVal[pow2+segPeak[pow2+i]]; } for (int b = 1; b < 20; b++) { for (int i = 0; i < n; i++) { int nxt = jmp[i][b-1]; if (nxt >= n) continue; jmp[i][b] = jmp[nxt][b-1]; } } } int max_towers(int L, int R, int D) { if (!initialized) init2(D); int res = 1; int cur = L; for (int b = 20-1; b >= 0; b--) { int nxt = jmp[cur][b]; if (nxt > R) continue; cur = nxt; res += 1 << b; } return res; } #ifdef TEST #include "stub.cpp" #endif
#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...