解析:
先用二分求出以a[i]为首的最长子序列长度,往后贪心着取就是了。
[code]:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define pb push_back
using namespace std;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
int n,m,a[maxn],b[maxn],dp[maxn];
vector<int> G[maxn];
int ans[maxn],top;
void init(){
int i;
for(i = 1;i <= n;i++) G[i].clear();
memset(dp,63,n*sizeof(int));
}
void sol(){
int i,j,p;
for(i = n-1;i >= 0;i--){
p = lower_bound(dp,dp+n,1e8-a[i])-dp;
//G[p+1].pb(i);
b[i] = p+1;
dp[p] = 1e8-a[i];
}
}
int main(){
int i,j,k,cas,p;
scanf("%d",&cas);
for(int T=1;T<=cas;T++){
scanf("%d%d",&n,&m);
init();
for(i = 0;i < n;i++) scanf("%d",&a[i]);
sol();
printf("Case %d:\n",T);
while(m--){
scanf("%d",&k);
p = -1;top = 0;
for(i = 0;i < n;i++){
if(k>0&&b[i] >= k&&(p==-1||p<a[i])){
ans[top++] = a[i];
p = a[i];
k--;
}
}
if(top==0) puts("Impossible");
else{
for(i = 0;i < top;i++){
if(i) putchar(' ');
printf("%d",ans[i]);
}
putchar('\n');
}
}
}
return 0;
}