daimayuan 608. 字典序最小
题意:
在长为n的数组中选一个字典序最小的子序列,要求这个子序列是 1~m 的排列。
保证答案存在。这字典序就是整数的字典序,不必按位考虑或者变成字符串之类的
\(1\le m \le n\le 1e6, 1\le a_i \le m\)
思路:
开一个单调栈,里面存的恰是 \(a_1\sim a_i\) 的答案。
对每个 \(a_i\),若整数 \(a_i\) 已在栈中就啥也不干,否则出栈比 \(a_i\) 小的数。注意要记录一下每个数出现的最后位置,若栈顶是该数的最后一个则不能出栈。
const signed N = 1e6 + 3;
int n, m, a[N], last[N];
int stk[N], tt; bool vis[N];
signed main() {
iofast;
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i], last[a[i]] = i;
for(int i = 1; i <= n; i++) {
if(vis[a[i]]) continue;
while(tt && stk[tt] > a[i] && last[stk[tt]] > i)
vis[stk[tt]] = 0, tt--;
stk[++tt] = a[i], vis[a[i]] = 1;
}
for(int i = 1; i <= m; i++)//这题最后不能有空格
cout << stk[i] << " \n"[i==m];
}

浙公网安备 33010602011771号