树状数组解决lis(最长上升序列),nlogn
用树状数组维护f数组小于等于i的最大值(前i位最值)
用到离散化
View Code
1 program sky; 2 var 3 c,a,f,b,s:array[0..50000] of longint; 4 i,j,n:longint; 5 ans,tot:longint; 6 function max(qq,ww:longint):longint; 7 begin 8 if qq>ww then exit(qq); exit(ww); 9 end; 10 procedure swap(var qq,ww:longint); 11 var 12 tp:longint; 13 begin 14 tp:=qq; qq:=ww; ww:=tp; 15 end; 16 procedure ins(w,y:longint); 17 begin 18 while y<=tot do 19 begin 20 c[y]:=max(c[y],w); 21 inc(y,y and -y); 22 end; 23 end; 24 function get(x:longint):longint; 25 begin 26 get:=0; 27 while x>0 do 28 begin 29 get:=max(get,c[x]); 30 dec(x,x and -x); 31 end; 32 end; 33 procedure qs(l,r:longint); 34 var 35 i,j,z:longint; 36 begin 37 i:=l; j:=r; z:=a[random(r-l)+l]; 38 repeat 39 while a[i]<z do inc(i); 40 while a[j]>z do dec(j); 41 if i<=j then 42 begin 43 swap(a[i],a[j]); swap(b[i],b[j]); 44 inc(i); dec(j); 45 end; 46 until i>j; 47 if i<r then qs(i,r); 48 if j>l then qs(l,j); 49 end; 50 begin 51 assign(input,'tiaoshi.in'); reset(input); 52 assign(output,'tiaoshi.out'); rewrite(output); 53 read(n); 54 for i:=1 to n do begin read(a[i]); b[i]:=i; end; 55 qs(1,n); 56 a[0]:=-1; 57 for i:=1 to n do 58 begin 59 if a[i]<>a[i-1] then inc(tot); 60 s[b[i]]:=tot; 61 end; 62 for i:=1 to n do f[i]:=1; 63 for i:=1 to n do 64 begin 65 f[i]:=get(s[i]-1)+1; 66 ins(f[i],s[i]); ///?????????? 67 end; 68 writeln(get(tot)); //注意上下一致,ins的时候插到了tot就停了,这也只能get到tot,或者都是n 69 //当n=9,tot=7时,get(9)会发现f[9]=0 ,f[8]=0就返回了,而正解应该get(7),get(6),get(4); 70 close(input); close(output); 71 end.
主要学习离散化,也学习一下树状数组还可以这样用。