题意:给出数列,每次询问求出长度为s且序号的字典序最小的上升序列
思路:最坑的就是这种题不给spj
先来一发lis,每个位置记录以此数为结尾的上升序列最短长度
然后输出时,在剩余的数足够的情况下选最前面的
代码:
#include <bits/stdc++.h>
#define N 10009
using namespace std;
int n,m,a[N],Stack[N],top,x,now[N];
void solve(int x)
{
int last=0;
for (int i=1;i<=n;i++)
if (now[i]>=x&&a[i]>last)
{
printf("%d%s",a[i],(x==1?"\n":" "));
x--;
if (!x) break;
last=a[i];
}
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
Stack[++top]=a[n];
now[n]=1;
for (int i=n;i>=1;i--)
{
if (a[i]<Stack[top]) Stack[++top]=a[i],now[i]=top;
else
{
int l=1,r=top,ans=0;
while (l<=r)
{
int mid=l+r>>1;
if (Stack[mid]>a[i]) ans=mid,l=mid+1;
else r=mid-1;
}
Stack[ans+1]=a[i];
now[i]=ans+1;
}
}
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d",&x);
if (x>top) puts("Impossible");
else solve(x);
}
return 0;
}