Submission #1082613

#TimeUsernameProblemLanguageResultExecution timeMemory
1082613WansurRadio Towers (IOI22_towers)C++17
100 / 100
1534 ms43600 KiB
#include "towers.h" #include <bits/stdc++.h> #define f first #define s second #define ent '\n' using namespace std; typedef long long ll; const int maxn = 1e5 + 12; int root[maxn], t[maxn * 30]; int L[maxn * 30], R[maxn * 30]; int p[20][maxn], lg[maxn]; int dp[maxn], a[maxn]; pair<int, int> ord[maxn]; map<int, int> position; int n, nv; int build(int l, int r){ int v = ++nv; if(l == r) return v; int mid = l + r >> 1; L[v] = build(l, mid); R[v] = build(mid+1, r); return v; } int upd(int v, int tl, int tr, int pos, int x){ int u = ++nv; if(tl == tr){ t[u] = x; return u; } L[u] = L[v], R[u] = R[v]; int mid = tl + tr >> 1; if(pos <= mid){ L[u] = upd(L[v], tl, mid, pos, x); } else{ R[u] = upd(R[v], mid+1, tr, pos, x); } t[u] = t[L[u]] + t[R[u]]; return u; } int get(int v, int tl, int tr, int l, int r){ if(tl > r || l > tr) return 0; if(tl >= l && tr <= r) return t[v]; int mid = tl + tr >> 1; return get(L[v], tl, mid, l, r) + get(R[v], mid+1, tr, l, r); } int get(int v, int tl, int tr, int k){ if(tl == tr) return tl; int mid = tl + tr >> 1; if(t[L[v]] >= k) return get(L[v], tl, mid, k); return get(R[v], mid+1, tr, k - t[L[v]]); } struct asd{ int mx, mn, x, y; } d[maxn * 4]; asd merge(asd x, asd y){ if(x.mx < 0) return y; if(y.mx < 0) return x; x.x = max({x.x, y.x, y.mx - x.mn}); x.y = max({x.y, y.y, x.mx - y.mn}); x.mx = max(x.mx, y.mx); x.mn = min(x.mn, y.mn); return x; } void build(int v, int tl, int tr){ if(tl == tr){ d[v].mx = d[v].mn = a[tl]; d[v].x = d[v].y = 0; } else{ int mid = tl + tr >> 1; build(v*2, tl, mid); build(v*2+1, mid+1, tr); d[v] = merge(d[v*2], d[v*2+1]); } } asd query(int v, int tl, int tr, int l, int r){ if(tl > r || l > tr) return {-1, -1, -1, -1}; if(tl >= l && tr <= r) return d[v]; int mid = tl + tr >> 1; return merge(query(v*2, tl, mid, l, r), query(v*2+1, mid+1, tr, l, r)); } int get(int l, int r){ if(l > r) return 0; int k = lg[r - l + 1]; return max(p[k][l], p[k][r - (1 << k) + 1]); } void init(int N, std::vector<int> H) { n = N; for(int i=1;i<=n;i++){ dp[i] = int(2e9) + 1; a[i] = p[0][i] = H[i - 1]; position[a[i]] = i; if(i > 1) lg[i] = lg[i / 2] + 1; } for(int k=1;k<20;k++){ for(int i=1;i + (1 << k) - 1 <= n;i++){ p[k][i] = max(p[k-1][i], p[k-1][i + (1 << (k - 1))]); } } stack<int> s; for(int i=1;i<=n;i++){ while(s.size() && a[s.top()] > a[i]){ s.pop(); } if(s.size()){ dp[i] = get(s.top() + 1, i - 1); } s.push(i); } while(s.size()) s.pop(); for(int i=n;i;i--){ while(s.size() && a[s.top()] > a[i]){ s.pop(); } if(s.size()){ dp[i] = min(dp[i], get(i + 1, s.top() - 1)); } s.push(i); ord[i] = {dp[i] - a[i], i}; } sort(ord + 1, ord + n + 1, [](pair<int, int> x, pair<int, int> y){ return x > y; }); root[0] = build(1, n); build(1, 1, n); for(int i=1;i<=n;i++){ root[i] = upd(root[i-1], 1, n, ord[i].s, 1); } } int max_towers(int l, int r, int d) { l++, r++; int i = l, j = r, pos = 0; for(int tl = 1, tr = n; tl <= tr;){ int mid = tl + tr >> 1; if(ord[mid].f >= d){ pos = mid; tl = mid + 1; } else tr = mid - 1; } int sx = get(root[pos], 1, n, 1, l - 1) + 1, sy = get(root[pos], 1, n, l, r), ans = sy; if(sy == 0){ i = j = position[query(1, 1, n, l, r).mn]; ans = 1; } else{ i = get(root[pos], 1, n, sx), j = get(root[pos], 1, n, sx + sy - 1); } int L = 0, R = 0; for(int tl = l + 1, tr = i - 1; tl <= tr;){ int mid = tl + tr >> 1; if(query(1, 1, n, mid, i-1).mx >= a[i] + d){ L = mid; tl = mid + 1; } else tr = mid - 1; } for(int tl = j + 1, tr = r - 1; tl <= tr;){ int mid = tl + tr >> 1; if(query(1, 1, n, j + 1, mid).mx >= a[j] + d){ R = mid; tr = mid - 1; } else tl = mid + 1; } if(L != 0 && query(1, 1, n, l, L).x >= d) ans++; if(R != 0 && query(1, 1, n, R, r).y >= d) ans++; return ans; }

Compilation message (stderr)

towers.cpp: In function 'int build(int, int)':
towers.cpp:22:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   22 |     int mid = l + r >> 1;
      |               ~~^~~
towers.cpp: In function 'int upd(int, int, int, int, int)':
towers.cpp:35:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   35 |     int mid = tl + tr >> 1;
      |               ~~~^~~~
towers.cpp: In function 'int get(int, int, int, int, int)':
towers.cpp:49:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   49 |     int mid = tl + tr >> 1;
      |               ~~~^~~~
towers.cpp: In function 'int get(int, int, int, int)':
towers.cpp:55:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   55 |     int mid = tl + tr >> 1;
      |               ~~~^~~~
towers.cpp: In function 'void build(int, int, int)':
towers.cpp:80:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   80 |         int mid = tl + tr >> 1;
      |                   ~~~^~~~
towers.cpp: In function 'asd query(int, int, int, int, int)':
towers.cpp:90:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   90 |     int mid = tl + tr >> 1;
      |               ~~~^~~~
towers.cpp: In function 'int max_towers(int, int, int)':
towers.cpp:148:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  148 |         int mid = tl + tr >> 1;
      |                   ~~~^~~~
towers.cpp:166:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  166 |         int mid = tl + tr >> 1;
      |                   ~~~^~~~
towers.cpp:174:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  174 |         int mid = tl + tr >> 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...