AT_arc125_c [ARC125C] LIS to Original Sequence 题解

发布时间 2024-01-13 21:40:53作者: HZOI-Shadow

题目传送门

前置知识

贪心 | 构造

解法

对于任意一个未加入序列 \(P\) 的数 \(x<A_{i}(1 \le i \le k-1)\),如果其放在了 \(A_{i}\) 的前面,会导致最长上升子序列长度加一,从而不符合题目要求。因此我们需要把 \(x\) 放在 \(A_{i}\) 后面,同理,为符合题目要求,我们仅选择放最小的那一个。

\(i=k\) 的时候,如果我们仍按照如上的思路,会导致剩下的数只能升序依次加入序列 \(P\),使得最长上升子序列长度变长,从而不符合题目要求。因此我们选择将其倒序输出,来保证最长上升子序列长度不变。

  • 之所以选择对 \(i=k\) 的情况进行特判,是为了满足字典序最小的要求。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define sort stable_sort 
#define endl '\n'
int a[300001],vis[300001];
deque<int>q;
int main()
{
    int n,k,i;
    cin>>n>>k;
    for(i=1;i<=k;i++)
    {
        cin>>a[i];
        vis[a[i]]=1;
    }
    for(i=1;i<=n;i++)
    {
        if(vis[i]==0)
        {
            q.push_back(i);
        }
    }
    for(i=1;i<=k-1;i++)
    {
        cout<<a[i]<<" ";
        if(q.empty()==0&&q.front()<a[i])
        {
            cout<<q.front()<<" ";
            q.pop_front();
        }
    }
    while(q.empty()==0&&q.back()>a[k])
    {
        cout<<q.back()<<" ";
        q.pop_back();
    }
    q.push_back(a[k]);
    while(q.empty()==0)
    {
        cout<<q.back()<<" ";
        q.pop_back();
    }
    return 0;
}