首先是否存在很容易。
考虑如何输出最小字典序的方案。注意。。是位子的字典序,不是值。。
那么这样的话,倒过来做一遍最长下降子序列。
f[i]
表示以
i
<script type="math/tex" id="MathJax-Element-1213">i</script>开头的最长上升子序列长度、找答案的时候就顺着找,每次满足条件就输出。
【代码】
#include <iostream>
#include <cstdio>
#include <algorithm>
#define N 10005
using namespace std;
typedef long long ll;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,m,tot;
int a[N],f[N],g[N];
int Find(int x)
{
int l=1,r=tot,rtn=0;
while(l<=r)
{
int mid=l+r>>1;
if(x<g[mid]) rtn=mid,l=mid+1;
else r=mid-1;
}
return rtn;
}
void Input_Init()
{
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=n;i;i--)
{
int t=Find(a[i]);
f[i]=t+1;g[t+1]=max(g[t+1],a[i]);
tot=max(tot,t+1);
}
}
void Get_Ans(int x)
{
int last=0;
for(int i=1;i<=n;i++) if(f[i]>=x&&a[i]>last)
{
printf("%d",a[i]);
if(x!=1)printf(" ");
last=a[i];
x--;
if(!x)break;
}
printf("\n");
}
void Solve()
{
m=read();
while(m--)
{
static int x;x=read();
if(x>tot) printf("Impossible\n");
else Get_Ans(x);
}
}
int main()
{
Input_Init();
Solve();
return 0;
}