#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int dp[N];
int a[N],valid[N],nxt[N],fen[N];
// void add()
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
int vt=1e6;
set<int> vis={vt+1};
nxt[0]=vt+1;
for(int i=1;i<=n;i++)
{
cin>>a[i];
auto it=vis.upper_bound(a[i]);
nxt[i]=*it;
vis.insert(a[i]);
valid[i]=i-1;
if(a[i-1]<=a[i])
{
valid[i]=valid[i-1];
}
}
dp[0]=0;
deque<int> cur;
cur.push_back(0);
// int mip=0;
for(int i=1;i<=n;i++)
{
// dp[cur[0]] <= dp[cur[1]] <= ..
dp[i]=i;
// dp[i]= min(dp[ip]) valid[i]-1<=ip and not element in prefix ip is in the range [a[ip+1],a[i]]
// dp[i] = min(dp[ip]) valid[i]<=ip<=i-1 and nxt[ip]>=a[i]
// for(int ip=i-1;ip>=valid[i];ip--)
// {
// if(nxt[ip+1]>=a[i])
// {
// dp[i]=min(dp[i],dp[ip]+1);
// }
// }
// add dp[i] at nxt[i]
int s=valid[i]-1,e=i;
while(s+1<e)
{
int mid=(s+e)/2;
if(nxt[mid+1]>=a[i])
{
e=mid;
}
else
{
s=mid;
}
}
if(e==i)
{
dp[i]=i;
}
else
{
// we need min dp
// [e..i-1]
auto it=lower_bound(begin(cur),end(cur),e);
dp[i]=min(dp[i],dp[*it]+1);
}
while(cur.size()>0 and dp[cur.back()]>=dp[i])
{
cur.pop_back();
}
cur.push_back(i);
// nxt[valid[i]] <= nxt[valid[i+1]] <= .. <= nxt[i]
}
cout<<dp[n]<<endl;
}
| # | 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... |