Description
降雷皇哈蒙很喜欢雷电,他想找到神奇的电光。
哈蒙有n条导线排成一排,每条导线有一个电阻值,神奇的电光只能从一根导线传到电阻比它大的上面,而且必须从左边向右传导,当然导线不必是连续的。
哈蒙想知道电光最多能通过多少条导线,还想知道这样的方案有多少。
Solution
很容易地发现这是一个求最长上升子序列,并求出方案数。
用单调队列就能够轻易求出最长子序列的长度,而方案数可以用一棵线段树维护,以大小为下标,维护一个区间当中最长子序列的长度以及它的方案数,然后每次插入的时候就查询比他小的区间中的最长长度,再尝试进行更新,最后答案就在第一个节点处。其实可以不用单独求一次最长子序列长度。
Code
const mo=123456789;
var
a,d:array[0..100000] of longint;
t:array[0..400000,1..2] of longint;
n,cas,i,wz,mx,maxn,ans:longint;
sum:int64;
function ef(x:longint):longint;
var l,r:longint;
begin
l:=0;r:=sum;
while l<r do
begin
ef:=(l+r+1)div 2;
if d[ef]<x then l:=ef else r:=ef-1;
end;
exit(l+1);
end;
procedure change(l,r,wz,x,y,z:longint);
var mid:longint;
begin
if l=r then
begin
if y>t[wz,1] then
begin
t[wz,1]:=y;t[wz,2]:=z;
end
else if y=t[wz,1] then t[wz,2]:=(t[wz,2]+z) mod mo;
exit;
end;
mid:=(l+r) div 2;
if x>mid then change(mid+1,r,wz*2+1,x,y,z) else change(l,mid,wz*2,x,y,z);
if t[wz*2,1]=t[wz*2+1,1] then
begin
t[wz,1]:=t[wz*2,1];t[wz,2]:=(t[wz*2,2]+t[wz*2+1,2]) mod mo;
end
else if t[wz*2,1]>t[wz*2+1,1] then
begin
t[wz,1]:=t[wz*2,1];t[wz,2]:=t[wz*2,2] mod mo;
end
else
begin
t[wz,1]:=t[wz*2+1,1];t[wz,2]:=t[wz*2+1,2] mod mo;
end;
end;
procedure get(l,r,wz,x,y:longint);
var mid:longint;
begin
if x>y then exit;
if (l=x)and(r=y) then
begin
if mx<t[wz,1] then
begin
mx:=t[wz,1];sum:=t[wz,2];
end
else if mx=t[wz,1] then sum:=(sum+t[wz,2])mod mo;
exit;
end;
mid:=(l+r)div 2;
if x>mid then get(mid+1,r,wz*2+1,x,y)
else if y<=mid then get(l,mid,wz*2,x,y)
else
begin
get(l,mid,wz*2,x,mid);
get(mid+1,r,wz*2+1,mid+1,y)
end;
end;
begin
readln(n,cas);
for i:=1 to n do
begin
read(a[i]);inc(a[i]);
if a[i]>maxn then maxn:=a[i];
end;
fillchar(d,sizeof(d),$7f);
d[0]:=0;
for i:=1 to n do
begin
wz:=ef(a[i]);
if d[wz]>a[i] then d[wz]:=a[i];
if wz>sum then sum:=wz;
end;
writeln(sum);
if cas<>1 then
begin
close(input);
close(output);
exit;
end;
for i:=1 to n do
begin
mx:=0;sum:=1;
get(1,maxn,1,1,a[i]-1);
if ans<mx+1 then ans:=mx+1;
change(1,maxn,1,a[i],mx+1,sum);
end;
writeln(t[1,2]);
end.