https://nanti.jisuanke.com/t/45345
題意:
給出n個數,找出它的子序列中,字典序最小的排序。
解析:
從前往後做,維護單調遞增的棧。
假設當前進棧的點是這種數裏面的最後一個,說明一定要取。此時棧內的所有元素都需要取(不取的話字典序會變大)。
只需要在彈出的時候判斷棧頂元素是否可以彈即可。
代碼:
/*
* 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*/