This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
#include "towers.h"
using namespace std;
#define all(fl) fl.begin(),fl.end()
#define pb push_back
#define fi first
#define se second
#define for1(i,j,k) for(int i=j;i<=k;i++)
#define for2(i,j,k) for(int i=j;i>=k;i--)
#define for3(i,j,k,l) for(int i=j;i<=k;i+=l)
#define lb lower_bound
#define ub upper_bound
#define sz(a) (int)a.size()
#define pii pair<int,int>
#define pli pair<long long,int>
#define gcd __gcd
#define lcm(x,y) x*y/__gcd(x,y)
#define pil pair<int,long long>
const int maxn=1e5+9;
int a[maxn],prv[maxn],nxt[maxn],mx1[maxn],mx2[maxn];
int st_max[maxn<<2];
void buildd(int id,int l,int r){
if (l==r){
st_max[id]=a[l];
return;
}
int mid=(l+r)>>1;
buildd(id<<1,l,mid);
buildd(id<<1|1,mid+1,r);
st_max[id]=max(st_max[id<<1],st_max[id<<1|1]);
}
int get_max(int id,int l,int r,int u,int v){
if (l>v||r<u||u>v)return 0;
if (u<=l&&r<=v)return st_max[id];
int mid=(l+r)>>1;
return max(get_max(id<<1,l,mid,u,v),get_max(id<<1|1,mid+1,r,u,v));
}
int n;
void build_pre(){
stack<int>t;
t.push(0);
for1(i,1,n){
while (!t.empty()&&a[t.top()]>a[i])t.pop();
prv[i]=t.top();
t.push(i);
mx1[i]=get_max(1,1,n,prv[i]+1,i-1)-a[i];
}
}
void build_suf(){
stack<int>t;
t.push(n+1);
for2(i,n,1){
while (!t.empty()&&a[t.top()]>a[i])t.pop();
nxt[i]=t.top();
t.push(i);
mx2[i]=get_max(1,1,n,i+1,nxt[i]-1)-a[i];
}
}
struct node{
vector<int>t;
int val,l,r;
node(){
t.clear();
val=l=r=0;
}
}st[10000009];
int lx[10000009],rx[10000009];
node cmp(const node &np, const node &nq,int d){
if (np.l==0)return nq;
if (nq.l==0)return np;
node p=np,q=nq,r;
r.val=p.val+q.val;
r.l=p.l,r.r=q.r;
while (!p.t.empty()){
auto u=p.t.back();
if (nxt[u]<=q.r&&nxt[u]>=q.l&&mx2[u]<d){
p.t.pop_back();
r.val--;
}
else break;
}
vector<int>tmp;
for (auto v:p.t){
tmp.pb(v);
}
for (auto v:q.t){
if (prv[v]>=p.l&&p.r>=prv[v]&&mx1[v]<d){
r.val--;
continue;
}
tmp.pb(v);
}
if (sz(tmp)==1){
r.t.pb(tmp[0]);
}
else if (sz(tmp)>=2){
r.t.pb(tmp[0]),r.t.pb(tmp.back());
}
return r;
}
int nnode=0;
int copy(int id){
nnode++;
lx[nnode]=lx[id];
rx[nnode]=rx[id];
return nnode;
}
int build(int id,int l,int r,int d){
st[id]=node();
st[id].l=l,st[id].r=r;
if (l==r){
st[id].val=1;
st[id].t.pb(l);
return id;
}
int mid=(l+r)>>1;
lx[id]=build(id<<1,l,mid,d);
rx[id]=build(id<<1|1,mid+1,r,d);
st[id]=cmp(st[id<<1],st[id<<1|1],d);
return id;
}
int update(int id,int l,int r,int u,int d){
if (l>u||r<u)return id;
if (l==r){
int newnode=copy(id);
st[newnode].val=1;
st[newnode].t.pb(l);
st[newnode].l=st[newnode].r=l;
return newnode;
}
int mid=(l+r)>>1;
int newnode=copy(id);
lx[newnode]=update(lx[id],l,mid,u,d);
rx[newnode]=update(rx[id],mid+1,r,u,d);
st[newnode]=cmp(st[lx[newnode]],st[rx[newnode]],d);
return newnode;
}
node get(int id,int l,int r,int u,int v,int d){
if (l>v||r<u||u>v)return node();
if (u<=l&&r<=v)return st[id];
int mid=(l+r)>>1;
return cmp(get(lx[id],l,mid,u,v,d),get(rx[id],mid+1,r,u,v,d),d);
}
vector<int>reup[maxn*2];
vector<int>value;
int root[maxn*2];
void init(int N, std::vector<int> H) {
n=N;
for1(i,1,n)a[i]=H[i-1];
buildd(1,1,n);
build_pre(),build_suf();
build(1,1,n,0);
value.pb(0);
for1(i,1,n){
mx1[i]=max(mx1[i],0),mx2[i]=max(mx2[i],0);
value.pb(mx1[i]),value.pb(mx2[i]);
}
sort(all(value));
value.resize(distance(value.begin(),unique(all(value))));
for1(i,1,n){
reup[lower_bound(all(value),mx1[i])-value.begin()].pb(i);
reup[lower_bound(all(value),mx2[i])-value.begin()].pb(i);
}
nnode=4*n;
root[0]=1;
for1(i,1,sz(value)-1){
root[i]=root[i-1];
for (auto v:reup[i]){
root[i]=update(root[i],1,n,v,value[i]+1);
}
}
}
int max_towers(int L, int R, int D) {
L++,R++;
int l=0,r=sz(value)-1,ans=0;
while (l<=r){
int mid=(l+r)>>1;
if (value[mid]<D){
ans=mid;
l=mid+1;
}
else r=mid-1;
}
node tmp=get(root[ans],1,n,L,R,D);
return tmp.val;
}
# | 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... |