可以发现最后的最长上升子序列是由原序列中从某一个点开始的最长上升子序列A和最长下降子序列B组合而成的,贡献的方案数为numA *numB。注意找到更长的以后要把原来的方案数清零。
假设最终最长长度为R,最后答案要乘上2^(N-R),因为其他元素可以任意选择放左边或右边。
求最长上升/下降子序列及方案数可以用树状数组做。经典的dp方程:F[i]=max{F[j]+1}(a[i]
type
node=record
t,s:int64;
end;
var
n,i,j:longint;
last,size,lq,ans1,ans2:int64;
a,b:array[0..500100]of int64;
c,l:array[0..500100]of node;
f1,g1,f2,g2:array[0..500100]of int64;
o:node;
const md=1000000007;
function max(x,y:int64):int64;
begin
if x>y then exit(y)
else exit(x);
end;
procedure qs(p,q:longint);
var
i,j:longint;
mid:int64;
tt:node;
begin
mid:=l[(p+q)div 2].t;
i:=p;
j:=q;
repeat
while l[i].tdo inc(i);
while l[j].t>mid do dec(j);
if i<=j then
begin
tt:=l[i];
l[i]:=l[j];
l[j]:=tt;
inc(i);
dec(j);
end;
until i>j;
if pthen qs(p,j);
if ithen qs(i,q);
end;
function lowbit(x:longint):longint;
begin
exit(x and(-x));
end;
function getmax(x:int64):node;
begin
getmax.t:=0;
getmax.s:=1;
while x>0 do
begin
if c[x].t=getmax.t then getmax.s:=(getmax.s+c[x].s)mod md;
if c[x].t>getmax.t then begin getmax.t:=c[x].t; getmax.s:=c[x].s; end;
x:=x-lowbit(x);
end;
end;
procedure updata(x,y,z:int64);
begin
while x<=size do
begin
if c[x].t=y then c[x].s:=(c[x].s+z)mod md;
if c[x].tthen begin c[x].t:=y; c[x].s:=z; end;
x:=x+lowbit(x);
end;
end;
function ksm(a,b:int64):int64;
begin
ksm:=1;
while b>0 do
begin
if b mod 2=1 then ksm:=(ksm*a)mod md;
a:=(a*a)mod md;
b:=b div 2;
end;
end;
begin
readln(n);
for i:=1 to n do
begin
read(a[i]);
l[i].t:=a[i];
l[i].s:=i;
end;
qs(1,n);
last:=0;
lq:=0;
for i:=1 to n do
if l[i].t=last then a[n-l[i].s+1]:=lq
else
begin
last:=l[i].t;
inc(lq);
a[n-l[i].s+1]:=lq;
end;
size:=lq;
fillchar(c,sizeof(c),0);
for i:=1 to n do
begin
o:=getmax(a[i]-1);
f1[i]:=o.t+1;
g1[i]:=o.s;
updata(a[i],f1[i],g1[i]);
end;
fillchar(c,sizeof(c),0);
for i:=1 to n do
begin
o:=getmax(size-a[i]);
f2[i]:=o.t+1;
g2[i]:=o.s;
updata(size-a[i]+1,f2[i],g2[i]);
end;
ans1:=0;
ans2:=0;
for i:=1 to n do
begin
if f1[i]+f2[i]-1=ans1 then ans2:=(ans2+(g1[i]*g2[i])mod md)mod md;
if f1[i]+f2[i]-1>ans1 then begin ans1:=f1[i]+f2[i]-1; ans2:=(g1[i]*g2[i])mod md; end;
end;
ans2:=(ans2*ksm(2,n-ans1))mod md;
writeln(ans1,' ',ans2);
end.