版权声明:本文为博主原创文章,转载时请注明原文地址=w=,希望对您有所帮助 https://blog.csdn.net/Eirlys_North/article/details/71083774
题意:给定序列ai,m个询问,每次询问是否存在长度问len的上升子序列,如果存在多个输出位置字典序最小的那个
判断是否存在长度为len的上升子序列只需要判断len与最长上升子序列的大小即可
对于这种最后要求字典序最小的答案自然是尽量把字典序小的放前面
那么我们就需要判断当前位置能否放在答案里
也就是以当前位置开始的最长上升子序列的长度是否不小于当前所需要的长度
也就是需要求出每个位置开始的最长上升子序列长度
等价于倒着做一遍最长下降子序列
uses math;
var
n,maxn,m,x :longint;
i :longint;
a,f,g :array[0..100010] of longint;
function find(x:longint):longint;
var
l,r,mid,ans:longint;
begin
l:=1; r:=maxn; ans:=0;
while l<=r do
begin
mid:=(l+r)>>1;
if g[mid]>x then
begin
ans:=mid; l:=mid+1
end else r:=mid-1;
end;
exit(ans);
end;
procedure pre_do;
var
i:longint;
begin
maxn:=0;
for i:=n downto 1 do
begin
f[i]:=find(a[i])+1;
maxn:=max(maxn,f[i]);
if g[f[i]]<a[i] then g[f[i]]:=a[i];
end;
end;
procedure solve(x:longint);
var
last,i:longint;
begin
last:=0;
for i:=1 to n do
if (f[i]>=x) and (a[i]>last) then
begin
write(a[i]);
if x=1 then writeln else write(' ');
dec(x);
last:=a[i];
if x=0 then exit;
end;
end;
begin
read(n);
for i:=1 to n do read(a[i]); a[0]:=-maxlongint;
pre_do;
read(m);
for i:=1 to m do
begin
read(x);
if x>maxn then writeln('Impossible') else solve(x);
end;
end.
——by Eirlys