我们按顺序从前往后在这 n 个数之中选 k 个数出来,一个自然的想法
就是每次尽量选取字典序最小的数,让较大的数在答案序列中尽量靠后。
我们可以用类似单调队列的思想去实现: 用 ans[] 存储答案,当枚举到第 i 个数 ai 的时候,当 ans[] 之中没有 ai 时,将其与 ans[] 的最后一位 b 做比较,如果 ai < b 且 ai 之后还有b,那么删去 b,接着比较,直到在 ans[] 中找到不满足条件的数为止,此时插入 ai,枚举下一个数。
涉及知识点:单调栈
#include <iostream>
using namespace std;
const int N = 200010;
int ans[N], cnt, n, m, p[N];
int a[N];
bool st[N];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
p[a[i]] = i;
}
for (int i = 1; i <= n; i ++) {
if (!st[a[i]]) {
st[a[i]] = 1;
while (cnt > 0 && a[i] < ans[cnt] && p[ans[cnt]] > i) st[ans[cnt]] = 0, cnt --;
ans[++ cnt] = a[i];
}
}
for (int i = 1; i <= m; i ++) cout << ans[i] << ' ';
return 0;
}