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.