BZOJ1046&&洛谷P2215 [HAOI2007]上升序列

我们平时求的lis是以i结尾,这道题要求i开头,那就倒着求就行了,n^2可做,nlogn最好

然后下面询问时,若当前询问大于最长的lis那就impossible,不然就从第一个f[i]>=询问的地方开始输出,这样下标字典序一定最小

代码

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; 
const int M=105000;
int n,m;
int a[M],f[M],cnt,dp[M];
inline int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
signed main()
{
	n=read();
	for (int i=1;i<=n;i++) a[i]=read();
	for (int i=n;i>=1;i--)
	{
		int l=1,r=cnt,emm=0;
		while (l<=r)
		{
			int mid=(l+r)>>1;
			if (dp[mid]>a[i]) emm=mid,l=mid+1;
			else r=mid-1;
		}
		f[i]=emm+1;
		cnt=max(cnt,f[i]);
		dp[f[i]]=max(dp[f[i]],a[i]);
	}
	m=read();
	while (m--)
	{
		int x=read();
		if (x>cnt){puts("Impossible");continue;}
		int qlm=0;
		for (int k=1;k<=n&&x;k++)
		if (f[k]>=x&&a[k]>qlm) 
		{
			cout<<a[k]<<" ";
			qlm=a[k];x--;
		}
		puts("");
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/ACerAndAKer/article/details/81407086