bzoj 1046
一看就知道是DP了。
注意要求字典序最小,所以要从后往前做最长下降子序列。
如果不加二分或者树状数组之类的优化应该会TLE的吧。
输出的时候找一下答案即可。
#include<cstdio> #include<cctype> #include<algorithm> using namespace std; int read(){ char c; while(!isdigit(c=getchar()) && c!='-'); int x=0,y=1; if(c=='-') y=-1; else x=c-'0'; while(isdigit(c=getchar())) x=x*10+c-'0'; return x*y; } int a[10001],f[10001],w[10001]; int find(int l,int r,int v){ while(l<=r){ int mid=l+r>>1; if(v<w[mid]) l=mid+1; else r=mid-1; } return l; } void print(int n,int l){ int pre=-2e9,fs=0; for(int i=1;i<=n && l;i+=1) if(pre<a[i] && f[i]>=l){ if(!fs) fs=1,printf("%d",a[i]); else printf(" %d",a[i]); pre=a[i]; l--; } printf("\n"); } int main(){ int n=read(),m=0; for(int i=1;i<=n;i+=1) a[i]=read(); for(int i=n;i>=1;i-=1){ f[i]=find(1,m,a[i]); if(m<f[i]) w[++m]=a[i]; else w[f[i]]=max(w[f[i]],a[i]); } int q=read(); while(q--){ int l=read(); if(l<1 || l>m) puts("Impossible"); else print(n,l); } return 0; }