[bzoj1046]上升序列
以i为开头的最长上升子序列,那么就是反过来以i为结尾的最长下降子序列,预处理出来后,不断向后找到下一个数即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 10005 4 int n,m,x,a[N],b[N],f[N]; 5 int find(int k){ 6 int l=0,r=b[0]; 7 while (l<r){ 8 int mid=(l+r+1>>1); 9 if (b[mid]>k)l=mid; 10 else r=mid-1; 11 } 12 return l; 13 } 14 int main(){ 15 scanf("%d",&n); 16 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 17 for(int i=n;i;i--){ 18 f[i]=find(a[i])+1; 19 b[0]=max(b[0],f[i]); 20 b[f[i]]=max(b[f[i]],a[i]); 21 } 22 scanf("%d",&m); 23 for(int i=1;i<=m;i++){ 24 scanf("%d",&x); 25 if (x>b[0])printf("Impossible\n"); 26 else{ 27 int last=0; 28 for(int j=1;j<=n;j++){ 29 if ((f[j]>=x)&&(a[j]>last)){ 30 printf("%d ",last=a[j]); 31 if (!--x)break; 32 } 33 } 34 printf("\n"); 35 } 36 } 37 }