[思路题][BZOJ2457][BeiJing2011]双端队列:贪心

分析:

不想写啊啊啊啊~
编号按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;
}

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9595453.html
今日推荐