树状数组

树状数组解决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.

主要学习离散化,也学习一下树状数组还可以这样用。

posted @ 2012-04-13 06:35  SunSky...  阅读(220)  评论(0编辑  收藏  举报