pku1631 Bridging signals
很老的一个连线不相交问题,左边的点已经有序,直接对右边的对应坐标求最长不降序列即可,数据较大,需要用nlogn的二分法。
View Code
1 program pku1631(input,output);
2 var
3 q : array[0..60000] of longint;
4 top : longint;
5 n : longint;
6 a : array[0..50000] of longint;
7 cases : longint;
8 procedure init;
9 var
10 i : longint;
11 begin
12 readln(n);
13 for i:=1 to n do
14 readln(a[i]);
15 fillchar(q,sizeof(q),0);
16 top:=0;
17 end; { init }
18 function find(worth : longint ):longint;
19 var
20 l,r,mid : longint;
21 begin
22 l:=1;
23 r:=top;
24 while l+1<r do
25 begin
26 mid:=(l+r)>>1;
27 if q[mid]<=worth then
28 l:=mid
29 else
30 r:=mid;
31 end;
32 exit(r);
33 end; { find }
34 procedure main;
35 var
36 i,j : longint;
37 begin
38 for i:=1 to n do
39 begin
40 if a[i]>=q[top] then
41 begin
42 inc(top);
43 q[top]:=a[i];
44 continue;
45 end;
46 if a[i]<q[1] then
47 begin
48 q[1]:=a[i];
49 continue;
50 end;
51 j:=find(a[i]);
52 if a[i]<q[j] then
53 q[j]:=a[i];
54 end;
55 writeln(top);
56 end; { main }
57 begin
58 readln(cases);
59 while cases>0 do
60 begin
61 init;
62 main;
63 dec(cases);
64 end;
65 end.
最近比较流行的一个最值序法求答案,一样是nlogn的,用到了树状数组求最值,可以看一看。
View Code
1 program pku1631(input,output);
2 var
3 max : array[0..50000] of longint;
4 a,pos : array[0..50000] of longint;
5 f : array[0..50000] of longint;
6 n,cases : longint;
7 answer : longint;
8 procedure init;
9 var
10 i : longint;
11 begin
12 readln(n);
13 fillchar(max,sizeof(max),0);
14 for i:=1 to n do
15 begin
16 pos[i]:=i;
17 readln(a[i]);
18 end;
19 fillchar(f,sizeof(f),0);
20 end; { init }
21 function lowbit(x :longint ):longint;
22 begin
23 exit(x and (-x));
24 end; { lowbit }
25 procedure insect(x,w : longint );
26 begin
27 while x<=n do
28 begin
29 if w>max[x] then
30 max[x]:=w;
31 x:=x+lowbit(x);
32 end;
33 end; { insect }
34 function find(x :longint ):longint;
35 begin
36 find:=0;
37 while x>0 do
38 begin
39 if max[x]>find then
40 find:=max[x];
41 x:=x-lowbit(x);
42 end;
43 end; { find }
44 procedure swap(var aa,bb :longint );
45 var
46 tt : longint;
47 begin
48 tt:=aa;
49 aa:=bb;
50 bb:=tt;
51 end; { swap }
52 procedure sort(p,q :longint );
53 var
54 i,j,m1,m2 : longint;
55 begin
56 i:=p;
57 j:=q;
58 m1:=a[(i+j)>>1];
59 m2:=pos[(i+j)>>1];
60 repeat
61 while (a[i]<m1)or((a[i]=m1)and(pos[i]<m2)) do
62 inc(i);
63 while (a[j]>m1)or((a[j]=m1)and(pos[j]>m2)) do
64 dec(j);
65 if i<=j then
66 begin
67 swap(a[i],a[j]);
68 swap(pos[i],pos[j]);
69 inc(i);
70 dec(j);
71 end;
72 until i>j;
73 if i<q then sort(i,q);
74 if j>p then sort(p,j);
75 end; { sort }
76 procedure main;
77 var
78 i : longint;
79 begin
80 answer:=0;
81 for i:=1 to n do
82 begin
83 f[pos[i]]:=find(pos[i])+1;
84 insect(pos[i],f[pos[i]]);
85 if f[pos[i]]>answer then
86 answer:=f[pos[i]];
87 end;
88 writeln(answer);
89 end; { main }
90 begin
91 readln(cases);
92 while cases>0 do
93 begin
94 init;
95 sort(1,n);
96 main;
97 dec(cases);
98 end;
99 end.