Bzoj 1046: [HAOI2007]上升序列 二分,递推

1046: [HAOI2007]上升序列

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3671  Solved: 1255
[Submit][Status][Discuss]

Description

对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ax2 < … < axm)。那么就称P为S的一个上升序列。如果有多个P满足条件,那么我们想求字典序最小的那个。任务给出S序列,给出若干询问。对于第i个询问,求出长度为Li的上升序列,如有多个,求出字典序最小的那个(即首先x1最小,如果不唯一,再看x2最小……),如果不存在长度为Li的上升序列,则打印Impossible.

Input

第一行一个N,表示序列一共有N个元素第二行N个数,为a1,a2,…,an 第三行一个M,表示询问次数。下面接M行每行一个数L,表示要询问长度为L的上升序列。

Output

对于每个询问,如果对应的序列存在,则输出,否则打印Impossible.

Sample Input

6
3 4 1 2 3 6
3
6
4
5

Sample Output

Impossible
1 2 3 6
Impossible

HINT

 

数据范围

N<=10000

M<=1000

 

Source

 题解:
二分+递推
不会。。。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define INF 1e9
 4 #define MAXN 10010
 5 int f[MAXN],a[MAXN],len[MAXN],mx,n,cc[MAXN];
 6 int read()
 7 {
 8     int s=0,fh=1;char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
11     return s*fh;
12 }
13 int ef(int k)
14 {
15     int l=1,r=mx,mid,ans=0;
16     while(l<=r)
17     {
18         mid=(l+r)/2;
19         if(f[mid]>k){ans=mid;l=mid+1;}
20         else r=mid-1;
21     }
22     return ans;
23 }
24 void print(int k)
25 {
26     int last=-1,lc=0,i;
27     for(i=1;i<=n;i++)
28     {
29         if(len[i]>=k&&a[i]>last)
30         {
31             k--;
32             cc[++lc]=a[i];
33             last=a[i];
34             if(k==0)break;
35         }
36     }
37     for(i=1;i<lc;i++)printf("%d ",cc[i]);printf("%d",cc[lc]);
38     printf("\n");
39 }
40 int main()
41 {
42     int i,tmp,m,k,j;
43     n=read();
44     for(i=1;i<=n;i++)a[i]=read();
45     memset(f,0,sizeof(f));
46     memset(len,0,sizeof(len));
47     mx=0;
48     for(i=n;i>=1;i--)
49     {
50         tmp=ef(a[i]);
51         len[i]=tmp+1;
52         f[tmp+1]=max(f[tmp+1],a[i]);
53         mx=max(mx,tmp+1);
54     }
55     m=read();
56     for(i=1;i<=m;i++)
57     {
58         k=read();
59         if(k>mx)printf("Impossible\n");
60         else
61         {
62             print(k);
63         }
64     }
65     fclose(stdin);
66     fclose(stdout);
67     return 0;
68 }

 

posted @ 2016-03-28 18:44  微弱的世界  阅读(229)  评论(0编辑  收藏  举报