Restoring the Permutation (thinking + multiset simulation)

https://codeforces.com/contest/1506/problem/E


Idea: The smallest and largest lexicographic order is better.

The maximum is to find the first number in the remaining set that is less than the current maximum number. Throw into the multiset two points and then position -1.

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
multiset<LL>s1,s2;
multiset<LL>::iterator it;
LL a[maxn];
bool vis[maxn];
vector<LL>ans1,ans2;
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL t;cin>>t;
  while(t--){
    s1.clear();s2.clear();
    ans1.clear();ans2.clear();
    LL n;cin>>n;
    for(LL i=0;i<n+10;i++) vis[i]=0;
    for(LL i=1;i<=n;i++) s1.insert(i),s2.insert(i);
    for(LL i=1;i<=n;i++) cin>>a[i];
    LL maxv=0;
    for(LL i=1;i<=n;i++){
        if(!vis[a[i]]){
           ans1.push_back(a[i]);
            ans2.push_back(a[i]);
            vis[a[i]]=true;
            s1.erase(a[i]);
            s2.erase(a[i]);
            maxv=max(maxv,a[i]);
        }
        else if(vis[a[i]]){
            LL temp=(*s1.begin());
            s1.erase(temp);
            ans1.push_back(temp);
               it=s2.lower_bound(maxv);
               it--;
               ans2.push_back(*it);
               s2.erase(*it);
        }
    }
    for(auto i:ans1){
        cout<<i<<" ";
    }
    cout<<"\n";
    for(auto i:ans2){
        cout<<i<<" ";
    }
    cout<<"\n";
  }
return 0;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/115249111
Recommended