#include "towers.h"
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
const int inf = 2e9;
const int maxn = 1e5 + 10;
const int logn = 20;
int n;
vector<int> h, vr, vl;
class Persistent_Segtree{
private:
vector<int> l, r, sum;
int create(){
l.push_back(0);
r.push_back(0);
sum.push_back(0);
return l.size() - 1;
}
int left( int pos ){
if( l[pos] == 0 ){ int aux = create(); l[pos] = aux; }
return l[pos];
}
int right( int pos ){
if( r[pos] == 0 ){ int aux = create(); r[pos] = aux; }
return r[pos];
}
public:
int update( int pos, int ini, int fim, int id, int val ){
int novo = create();
if( ini > id || id > fim ) return novo;
if( ini == fim ){ sum[novo] = 1; return novo; }
int mid = ( ini + fim )/2;
if( id <= mid ){ l[novo] = update( left(pos), ini, mid, id, val ); r[novo] = right(pos); }
else{ l[novo] = left(pos); r[novo] = update( right(pos), mid + 1, fim, id, val ); }
sum[novo] = sum[l[novo]] + sum[r[novo]];
return novo;
}
int query( int pos, int ini, int fim, int ki, int kf ){
if( ki > fim || ini > kf || pos == 0 ) return 0;
if( ki <= ini && fim <= kf ) return sum[pos];
int mid = ( ini + fim )/2;
return query( left(pos), ini, mid, ki, kf ) + query( right(pos), mid + 1, fim, ki, kf );
}
Persistent_Segtree(){ create(); create(); }
} seg;
vector<pii> roots( 1, pii( inf, 1 ) );
void init(int N, vector<int> H) {
h = H;
n = N;
vr.resize(n);
vl.resize(n);
// achar primeiro menor a esq e dir
vector<int> l(n, -1), r(n, n);
stack<pair<int, int>> pilha;
pilha.push({-1, -inf});
for( int i = 0; i < n; i++ ){
while( pilha.top().second > h[i] ){
r[pilha.top().first] = i;
pilha.pop();
}
l[i] = pilha.top().first;
pilha.push({ i, h[i] });
}
vector<vector<int>> maxi( n, vector<int>(logn));
for( int i = 0; i < n; i++ ) maxi[i][0] = h[i];
for( int k = 1; k < logn; k++ )
for( int i = 0; i < n - (1<<k) + 1; i++ ) maxi[i][k] = max( maxi[i][k - 1], maxi[i + (1<<(k - 1))][k - 1] );
auto query = [&]( int a, int b ){
if( a > b ) return -inf;
int k = 31 - __builtin_clz(b - a + 1);
return max( maxi[a][k], maxi[b - (1<<k) + 1][k] );
};
vector<pii> v(n);
for( int i = 0; i < n; i++ ){
if( l[i] == -1 ) vl[i] = inf;
else vl[i] = query(l[i] + 1, i - 1) - h[i];
if( r[i] == n ) vr[i] = inf;
else vr[i] = query(i + 1, r[i] - 1) - h[i];
v[i].first = min( vl[i], vr[i] );
v[i].second = i;
}
sort( v.rbegin(), v.rend() );
for( auto [val, id] : v ){
auto [last_val, last_root] = roots.back();
int nova_root = seg.update( last_root, 0, n - 1, id, 1 );
if( val == last_val ) roots.pop_back();
roots.push_back({ val, nova_root });
}
reverse( roots.begin(), roots.end() );
}
int max_towers(int l, int r, int d) {
int id = upper_bound( roots.begin(), roots.end(), pii( d, -inf ) ) - roots.begin();
int root = roots[id].second;
int resp = seg.query( root, 0, n - 1, l + 1, r - 1 );
if( vr[l] >= d ) resp++;
if( vl[r] >= d ) resp++;
return resp;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |