#include<iostream>
#include<stack>
#include<map>
#include<vector>
#include<string>
#include<cassert>
#include<unordered_map>
#include <queue>
#include <cstdint>
#include<cstring>
#include<limits.h>
#include<cmath>
#include<set>
#include<algorithm>
#include <iomanip>
#include<numeric>
#include<bitset>
using namespace std;
#define ll long long
#define f first
#define s second
#define pii pair<int,int>
#define ppii pair<int,pii>
#define vi vector<int>
#define pb push_back
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define F(n) for(int i=0;i<n;i++)
#define lb lower_bound
#define ub upper_bound
#define fastio ios::sync_with_stdio(false);cin.tie(NULL);
#pragma GCC optimize ("03,unroll-lopps")
#define int long long
using namespace std;
const int mod=1e9+7,mxn=5e5,inf=1e18,minf=-1e18,lg=30,base=191,Mx=1e5;
//#undef int
int n;
int have[mxn+10],dist[mxn+10],L[mxn+10],R[mxn+10];
int mark[mxn+10],arrival[mxn+10];
//ct=latest time arrving at i
struct seg{
//keeping the min(2*(i-1)-cti)
int v[4*mxn+10],add[4*mxn+10];
void init(int n){for(int i=0;i<=4*n;i++)v[i]=inf,add[i]=0;}
void push(int l,int r,int pos){
v[pos]+=add[pos];
if(l!=r){
add[pos*2]+=add[pos];
add[pos*2+1]+=add[pos];
}
add[pos]=0;
}
void update(int l,int r,int ql,int qr,int pos,int val){
if(qr<ql)return;
push(l,r,pos);
if(l>qr||r<ql)return;
if(ql<=l&&r<=qr){
add[pos]=val;
push(l,r,pos);
return;
}
int mid=l+(r-l)/2;
update(l,mid,ql,qr,pos*2,val);
update(mid+1,r,ql,qr,pos*2+1,val);
v[pos]=min(v[pos*2],v[pos*2+1]);
}
int qryr(int l,int r,int ql,int qr,int pos){
if(qr<ql)return inf;
push(l,r,pos);
if(l>qr||r<ql)return inf;
if(ql<=l&&r<=qr)return v[pos];
int mid=l+(r-l)/2;
return min(qryr(l,mid,ql,qr,pos*2),qryr(mid+1,r,ql,qr,pos*2+1));
}
int qry(int l,int r,int pos,int qpos){
push(l,r,pos);
if(l==r)return v[pos];
int mid=l+(r-l)/2;
if(qpos<=mid)return qry(l,mid,pos*2,qpos);
return qry(mid+1,r,pos*2+1,qpos);
}
void updatepos(int l,int r,int pos,int qpos,int val){
push(l,r,pos);
if(l==r){
v[pos]=min(v[pos],val);
return;
}
int mid=l+(r-l)/2;
if(qpos<=mid)updatepos(l,mid,pos*2,qpos,val);
else updatepos(mid+1,r,pos*2+1,qpos,val);
v[pos]=min(v[pos*2],v[pos*2+1]);
}
void updp(int pos,int val){updatepos(0,n+1,1,pos,val);}
void updr(int l,int r,int val){update(0,n+1,l,r,1,val);}
int q(int pos){return qry(0,n+1,1,pos);}
int qr(int l,int r){return qryr(0,n+1,l,r,1);}
}t;
struct fen{
int fwk[mxn+10];
//keeping cti
void update(int pos,int val){
for(int i=pos;i<=n;i+=(i&-i))fwk[i]+=val;
}
int qry(int pos){
int sum=0;
for(int i=pos;i>0;i-=(i&-i))sum+=fwk[i];
return sum;
}
}ct;
bool cmp(pii a,pii b){
if(a.f==b.f)return a.s>b.s;
return a.f<b.f;
}
int32_t main(){
fastio
cin>>n;
int sum=0;
int cl=0;
for(int i=1;i<=n;i++){
cin>>have[i];
if(have[i]!=-1)sum+=have[i];
else cl=i;
}
int last=inf;
for(int i=1;i<=n;i++){
L[i]=last;
if(have[i]==-1)last=i;
}
last=inf;
for(int i=n;i>=1;i--){
R[i]=last;
if(have[i]==-1)last=i;
}
vector<pii>v;
for(int i=1;i<=n;i++)if(have[i]!=-1&&have[i]){
if(abs(L[i]-i)<abs(R[i]-i)){
arrival[i]=i-1;
dist[i]=abs(L[i]-i);
}
else{
arrival[i]=R[i]-1+R[i]-i;
dist[i]=abs(R[i]-i);
}
ct.update(i,arrival[i]-ct.qry(i));
v.pb({dist[i],i});
}
sort(all(v),cmp);
//its optimal following this order??
int ans=0;
t.init(n);
for(int i=v.size()-1;i>=0;i--){
//take 1 free
int cur=v[i].s;
if(R[cur]==inf||mark[R[cur]])continue;
t.updp(cur,cur-1);
sum--;
mark[R[cur]]=1;
have[cur]--;
}
sort(all(v));
for(auto i:v){
if(have[i.s]==0)continue;
int k=ct.qry(i.s);
int x=min(((2*(i.s-1))-k+(2*i.f))/(2*i.f),t.qr(i.s,n)/(2*i.f));
x=min(have[i.s],x);
x=max(0LL,x);
ans+=x;
ct.update(i.s,2*i.f*x);
t.updr(i.s,n,-2*i.f*x);
t.updp(i.s,2*(i.s-1)-k-(2*(x-1)*i.f));
//ct+2*take*dist<=2*x
//take<=(2*x-ct)/2(dist)
}
cout<<sum-ans<<'\n';
}
/*
bound max answer = n/2
bound max time = 2n
its optimal to use playgrounds and shops left to right
if we move from playgrounds a->b we can buy 1 thing on the way
o(n^3)->dp[at][time] state n^2, transition time n/2 (how many we buy)
is it always optimal to reach the playground before the othery guy does??
*/
컴파일 시 표준 에러 (stderr) 메시지
tortoise.cpp:32:40: warning: bad option '-funroll-lopps' to pragma 'optimize' [-Wpragmas]
32 | #pragma GCC optimize ("03,unroll-lopps")
| ^
tortoise.cpp:44:24: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
44 | void init(int n){for(int i=0;i<=4*n;i++)v[i]=inf,add[i]=0;}
| ^
tortoise.cpp:45:38: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
45 | void push(int l,int r,int pos){
| ^
tortoise.cpp:53:62: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
53 | void update(int l,int r,int ql,int qr,int pos,int val){
| ^
tortoise.cpp:67:51: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
67 | int qryr(int l,int r,int ql,int qr,int pos){
| ^
tortoise.cpp:75:45: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
75 | int qry(int l,int r,int pos,int qpos){
| ^
tortoise.cpp:82:60: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
82 | void updatepos(int l,int r,int pos,int qpos,int val){
| ^
tortoise.cpp:93:34: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
93 | void updp(int pos,int val){updatepos(0,n+1,1,pos,val);}
| ^
tortoise.cpp:94:38: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
94 | void updr(int l,int r,int val){update(0,n+1,l,r,1,val);}
| ^
tortoise.cpp:95:22: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
95 | int q(int pos){return qry(0,n+1,1,pos);}
| ^
tortoise.cpp:96:27: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
96 | int qr(int l,int r){return qryr(0,n+1,l,r,1);}
| ^
tortoise.cpp:101:32: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
101 | void update(int pos,int val){
| ^
tortoise.cpp:104:20: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
104 | int qry(int pos){
| ^
tortoise.cpp:110:21: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
110 | bool cmp(pii a,pii b){
| ^
tortoise.cpp:114:14: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
114 | int32_t main(){
| ^
# | 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... |