Perfect Flush(單調棧 想法)

https://nanti.jisuanke.com/t/45345

題意:

給出n個數[1,k]\in[1,k],找出它的子序列中,字典序最小的排序。

解析:

從前往後做,維護單調遞增的棧。

假設當前進棧的點是這種數裏面的最後一個,說明一定要取。此時棧內的所有元素都需要取(不取的話字典序會變大)。

只需要在彈出的時候判斷棧頂元素是否可以彈即可。

代碼:

/*
 *  Author : Jk_Chen
 *    Date : 2020-05-04-13.24.42
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<"> "<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=2e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

int n,k;
int a[maxn];
int ct[maxn];

int sta[maxn],top;
bool use[maxn];
bool in[maxn];

int main(){
    n=rd,k=rd;
    rep(i,1,n)a[i]=rd,ct[a[i]]++;;

    rep(i,1,n){
        ct[a[i]]--;
        if(in[a[i]])continue;
        while(top&&a[i]<=a[sta[top]]&&ct[a[sta[top]]]){
            in[a[sta[top]]]=0;
            top--;
        }
        sta[++top]=i;
        in[a[i]]=1;
    }

    rep(i,1,top){
        printf("%d%c",a[sta[i]]," \n"[i==top]);
    }

    return 0;
}
/*
9 4
3 1 4 2 1 3 3 4 2
*/
/*_________________________________________________________end*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章