分析:
不想写啊啊啊啊~
编号按a[i]排序后相等的合并然后贪心求最少的单谷区间(姑且这么叫吧)。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
inline LL read(){
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=200005;
int n,f[MAXN],m,g[MAXN][2];
LL a[MAXN];
inline bool cmp(int x,int y){
return a[x]<a[y];
}
int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read(),f[i]=i;
sort(f+1,f+n+1,cmp);
a[0]=1e18;
for(int i=1;i<=n;i++){
if(a[f[i]]!=a[f[i-1]]) g[++m][0]=g[m][1]=f[i];
else g[m][0]=min(g[m][0],f[i]),g[m][1]=max(g[m][1],f[i]);
}
bool flag=0;int ans=1,pre=g[1][0];
for(int i=2;i<=m;i++){
if(flag&&g[i][0]<pre) ans++,pre=g[i][0],flag=0;
else if(flag&&g[i][0]>pre) pre=g[i][1];
else if(!flag&&g[i][1]>pre) flag=1,pre=g[i][1];
else pre=g[i][0];
}
printf("%d\n",ans);
return 0;
}