SGU 174 Wall

一道看起来算法很明确的题目:给定N条平面上的线段,问最早在哪条线段处出现封闭图形,保证线段不相交。

对平面上的点进行离散,之后用并查集维护,一旦出现两个端点在同一集合中,终止算法,输出即可。

离散化的地方有必要说一下,很多人用HASH,很慢的,有人用平衡树,C++调库,psacal就吃了亏——

说一下本人离散方法,三棵平衡树,第一棵存x坐标,第二棵存y坐标,第三棵存{(x在一中的排位)*一中的x个数+(y在二中的排位)}

这样可以确定每个坐标都对应三中的一个值,不会有重复。

AC的感觉不错!

还要墨迹几句,SGU交pascal不能用exit(x),真不爽啊

View Code
  1 program sgu174(input,output);
2 type
3 node = record
4 x1,y1,x2,y2 : longint;
5 end;
6 var
7 left,right,s : array[0..1000000] of longint;
8 key : array[0..1000000] of longint;
9 father : array[0..500000] of longint;
10 tot,n : longint;
11 root1,root2,root3 : longint;
12 ask : array[0..210000] of node;
13 procedure left_rotate(var t: longint );
14 var
15 k : longint;
16 begin
17 k:=right[t];
18 right[t]:=left[k];
19 left[k]:=t;
20 s[k]:=s[t];
21 s[t]:=s[left[t]]+s[right[t]]+1;
22 t:=k;
23 end; { left_rotate }
24 procedure right_rotate(var t :longint );
25 var
26 k : longint;
27 begin
28 k:=left[t];
29 left[t]:=right[k];
30 right[k]:=t;
31 s[k]:=s[t];
32 s[t]:=s[left[t]]+s[right[t]]+1;
33 t:=k;
34 end; { right_rotate }
35 procedure maintain(var t : longint;flag:boolean);
36 begin
37 if flag=false then
38 if s[left[left[t]]]>s[right[t]] then
39 right_rotate(t)
40 else
41 if s[right[left[t]]]>s[right[t]] then begin
42 left_rotate(left[t]);
43 right_rotate(t);
44 end
45 else
46 exit
47 else
48 if s[right[right[t]]]>s[left[t]] then
49 left_rotate(t)
50 else
51 if s[left[right[t]]]>s[left[t]] then begin
52 right_rotate(right[t]);
53 left_rotate(t);
54 end
55 else
56 exit;
57 maintain(left[t],false);
58 maintain(right[t],true);
59 maintain(t,true);
60 maintain(t,false);
61 end;
62 procedure insect(var t : longint; k:longint );
63 begin
64 if t=0 then
65 begin
66 inc(tot);
67 t:=tot;
68 left[t]:=0;
69 right[t]:=0;
70 s[t]:=1;
71 key[t]:=k;
72 end
73 else
74 begin
75 inc(s[t]);
76 if k>=key[t] then
77 insect(right[t],k)
78 else
79 insect(left[t],k);
80 maintain(t,k>=key[t]);
81 end;
82 end; { insect }
83 function find(t : longint;k:longint ):boolean;
84 begin
85 if t=0 then
86 begin
87 find:=false;
88 exit;
89 end;
90 if key[t]>k then
91 begin
92 find:=find(left[t],k);
93 exit;
94 end
95 else
96 begin
97 find:=(key[t]=k)or(find(right[t],k));
98 exit;
99 end;
100 end; { find }
101 function rank(t : longint; k:longint ):longint;
102 begin
103 if t=0 then
104 begin
105 rank:=1;
106 exit;
107 end;
108 if key[t]>=k then
109 begin
110 rank:=rank(left[t],k);
111 exit;
112 end
113 else
114 begin
115 rank:=rank(right[t],k)+s[left[t]]+1;
116 exit;
117 end;
118 end; { rank }
119 procedure init;
120 var
121 i : longint;
122 tmpx,tmpy : longint;
123 begin
124 root1:=0;
125 root2:=0;
126 root3:=0;
127 tot:=0;
128 readln(n);
129 for i:=1 to n do
130 begin
131 readln(ask[i].x1,ask[i].y1,ask[i].x2,ask[i].y2);
132 if not find(root1,ask[i].x1) then
133 insect(root1,ask[i].x1);
134 if not find(root1,ask[i].x2) then
135 insect(root1,ask[i].x2);
136 if not find(root2,ask[i].y1) then
137 insect(root2,ask[i].y1);
138 if not find(root2,ask[i].y2) then
139 insect(root2,ask[i].y2);
140 end;
141 for i:=1 to n do
142 begin
143 tmpx:=rank(root1,ask[i].x1);
144 tmpy:=rank(root2,ask[i].y1);
145 if not find(root3,tmpx*s[root1]+tmpy) then
146 insect(root3,tmpx*s[root1]+tmpy);
147 tmpx:=rank(root1,ask[i].x2);
148 tmpy:=rank(root2,ask[i].y2);
149 if not find(root3,tmpx*s[root1]+tmpy) then
150 insect(root3,tmpx*s[root1]+tmpy);
151 end;
152 end; { init }
153 function getfather(x :longint ):longint;
154 begin
155 if father[x]=x then
156 begin
157 getfather:=x;
158 exit;
159 end;
160 father[x]:=getfather(father[x]);
161 getfather:=father[x];
162 end; { getfather }
163 procedure main;
164 var
165 i : longint;
166 x,y : longint;
167 tmpx,tmpy : longint;
168 begin
169 for i:=1 to 2*n do
170 father[i]:=i;
171 for i:=1 to n do
172 begin
173 tmpx:=rank(root1,ask[i].x1);
174 tmpy:=rank(root2,ask[i].y1);
175 x:=rank(root3,tmpx*s[root1]+tmpy);
176 tmpx:=rank(root1,ask[i].x2);
177 tmpy:=rank(root2,ask[i].y2);
178 y:=rank(root3,tmpx*s[root1]+tmpy);
179 x:=getfather(x);
180 y:=getfather(y);
181 if x=y then
182 begin
183 writeln(i);
184 exit;
185 end;
186 father[x]:=y;
187 end;
188 writeln(0);
189 end; { main }
190 begin
191 init;
192 main;
193 end.



posted @ 2012-03-07 18:18  Codinginging  阅读(350)  评论(0编辑  收藏  举报