POJ 2528

POJ 2528

题目大意:同上,只是x,y属于[1,10000000],最后询问能在这个[1,10000000]区间上能看见多少种颜色。

解:线段树+离散化,把可能的端点值存起来,排序,在对应回去,然后线段数即可,1re是因为tree数组的大小没有考虑到端点数*2而再*2,2tle是因为find写错了,然后3wa是因为离散化?这里是个重点,因为离散化之后比如[1,2][4,5],虽然中间有区间[3,3]但是如果按上文离散化则会出问题,奇怪的是我的处理+上这个判断,如果两个数之间有其他数,则再离散化多这个中间数,但是wa了,有空回来复习的时候检查一下,把特殊处理删除反而ac了,第二天过来看,看了别人的帖子,说把每个端点+1,-1也离散化即可,试了试ac了。

View Code
  1 //poj 2528
2 const
3 maxn=11111;
4 inf='1.txt';
5 type
6 data=record
7 mid, l, r, st, ed, c: longint;
8 end;
9 dota=record
10 l, r: longint;
11 end;
12 var
13 tmp, void: array[0..maxn*6]of longint;
14 a: array[0..maxn]of dota;
15 tree: array[0..maxn*4*6{!!!!!}]of data;
16 col: array[0..maxn]of boolean;
17 tot, len, ans, test, n: longint;
18 procedure _qsort(b, e: longint);
19 var
20 i, j, k, x: longint;
21 begin
22 i := b; j := e;
23 x := tmp[(i+j)>>1];
24 repeat
25 while (tmp[i]<x) do inc(i);
26 while (tmp[j]>x) do dec(j);
27 if i<=j then begin
28 k := tmp[i]; tmp[i] := tmp[j]; tmp[j] := k;
29 inc(i); dec(j);
30 end;
31 until i>j;
32 if j>b then _qsort(b, j);
33 if i<e then _qsort(i, e);
34 end;
35
36 function _find(x: longint): longint;
37 var
38 left, right, mid: longint;
39 begin
40 left := 1; right := tot;
41 while left<=right do begin
42 mid := (left+right)>>1;
43 if void[mid]=x then break;
44 if void[mid]>x then right := mid-1;
45 if void[mid]<x then left := mid+1;
46 end;
47 exit(mid);
48 end;
49
50 procedure _together;
51 var
52 i, j: longint;
53 begin
54 _qsort(1, len);
55 tot := 0; i := 1;
56 while i<=len do begin
57 inc(tot); void[tot] := tmp[i];
58 inc(i);
59 while (tmp[i]=tmp[i-1])and(i<=len) do inc(i);
60 {if (i<=len)and(tmp[i]-tmp[i-1]>1) then begin
61 inc(tot); void[tot] := tmp[i]-1;
62 end; }
63 end;
64 for i := 1 to n do with a[i] do begin
65 l := _find(l);
66 r := _find(r);
67 end;
68 end;
69
70 procedure _build(const s, e, k: longint);
71 begin
72 with tree[k] do begin
73 st := s; ed := e; c := 0;
74 mid := (s+e)>>1;
75 if s=e then exit;
76 l := k << 1; _build(st, mid, l);
77 r := l + 1; _build(mid+1, ed, r);
78 end;
79 end;
80
81 procedure _init;
82 var
83 i: longint;
84 begin
85 tot := 0; ans := 0;
86 readln(n);
87 for i := 1 to n do with a[i] do begin
88 readln(l, r);
89 inc(tot); tmp[tot] := l;
90 inc(tot); tmp[tot] := l-1; {!!!}
91 inc(tot); tmp[tot] := l+1;
92 inc(tot); tmp[tot] := r;
93 inc(tot); tmp[tot] := r-1;
94 inc(tot); tmp[tot] := r+1;
95 end;
96 len := tot;
97 _together;
98 _build(1, tot, 1);
99 end;
100
101 procedure _cover(const s, e, k, color: longint);
102 begin
103 with tree[k] do begin
104 if (s<=st)and(ed<=e) then begin
105 c := color; exit;
106 end;
107 if c>0 then begin
108 tree[l].c := c; tree[r].c := c;
109 c := 0;
110 end;
111 if s<=mid then _cover(s, e, l, color);
112 if e>mid then _cover(s, e, r, color);
113 end;
114 end;
115
116 procedure _count(s, e, k: longint);
117 begin
118 with tree[k] do begin
119 if c>0 then begin
120 col[c] := true; exit;
121 end;
122 if st=ed then exit;
123 _count(s, mid, l);
124 _count(mid+1, e, r);
125 end;
126 end;
127
128 procedure _main;
129 var
130 i: longint;
131 begin
132 for i := 1 to n do with a[i] do
133 _cover(l, r, 1, i);
134 _count(1, tot, 1);
135 for i := 1 to n do
136 if col[i] then begin
137 inc(ans); col[i] := false;
138 end;
139 end;
140
141 procedure _print;
142 begin
143 writeln(ans);
144 end;
145
146 var
147 i: longint;
148
149 begin
150 assign(input,inf); reset(input);
151 fillchar(col, sizeof(col), 0);
152 readln(test);
153 for i := 1 to test do begin
154 _init;
155 _main;
156 _print;
157 end;
158 end.



posted @ 2012-04-06 20:10  F.D.His.D  阅读(193)  评论(0编辑  收藏  举报