pku3225 区间

设计一个程序,能够在logn的时间内求出两个区间的并,交,相对补,相对差。

一个区间内如果为1,就表示这个区间存在,为0表示不存在。

线段树的应用,lazy思想的完美应用,对于一个节点,

cm标记为1时,表示其区间内均为1,0表示区间内均为0,2表示区间内既有0又有1

cx标记取反,为1时表示区间取反,0时表示不取反。

标记下传时cm优先。

U:把区间[l,r]覆盖成1
I:把[-∞,l)(r,∞]覆盖成0
D:把区间[l,r]覆盖成0
C:把[-∞,l)(r,∞]覆盖成0 , 且[l,r]区间0/1互换
S:[l,r]区间0/1互换

poj数据NND没有判错,得自己判,错的当∅还不能忽略,最阴的地方有这种数据:[x,x)

View Code
  1 program pku3225(input,output);
  2 const
  3     oo=140000;
  4 type
  5     node=record
  6         left,right,x,y:longint;
  7         xm,cm:integer;
  8     end;
  9     node2=record
 10         x,y:longint;
 11     end;
 12 var
 13     tree             :array[0..300000] of node;
 14     tot              :longint;
 15     fx,fy            :longint;
 16     number1,number2:longint;
 17     answer1,answer2:array[0..200000] of node2;
 18 procedure build(xx,yy:longint);
 19 var
 20     now,mid:longint;
 21 begin
 22     inc(tot);
 23     tree[tot].x:=xx;
 24     tree[tot].y:=yy;
 25     tree[tot].xm:=0;
 26     tree[tot].cm:=0;
 27     now:=tot;
 28     if xx=yy then
 29         exit;
 30     mid:=(xx+yy)>>1;
 31     tree[now].left:=tot+1;
 32     build(xx,mid);
 33     tree[now].right:=tot+1;
 34     build(mid+1,yy);
 35 end; { build }
 36 procedure down(now:longint);
 37 begin
 38     if (tree[now].cm=2)and(tree[now].xm=1) then
 39     begin
 40         if tree[now].left<>0 then
 41         begin
 42             if tree[tree[now].left].cm=2 then
 43                 tree[tree[now].left].xm:=1-tree[tree[now].left].xm
 44             else
 45                 tree[tree[now].left].cm:=1-tree[tree[now].left].cm;
 46         end;
 47         if tree[now].right<>0 then
 48         begin
 49             if tree[tree[now].right].cm=2 then
 50                 tree[tree[now].right].xm:=1-tree[tree[now].right].xm
 51             else
 52                 tree[tree[now].right].cm:=1-tree[tree[now].right].cm;
 53         end;
 54         tree[now].xm:=0;
 55     end
 56     else
 57     begin
 58         if (tree[now].cm=1)or(tree[now].cm=0) then
 59         begin
 60             if tree[now].left<>0 then
 61             begin
 62                 tree[tree[now].left].cm:=tree[now].cm;
 63                 tree[tree[now].left].xm:=0;
 64             end;
 65             if tree[now].right<>0 then
 66             begin
 67                 tree[tree[now].right].cm:=tree[now].cm;
 68                 tree[tree[now].right].xm:=0;
 69             end;
 70         end;
 71     end;
 72 end; { down }
 73 procedure insert(now,color:longint);
 74 var
 75     mid:longint;
 76 begin
 77     if (tree[now].x>=fx)and(tree[now].y<=fy) then
 78     begin
 79         tree[now].xm:=0;
 80         tree[now].cm:=color;
 81         exit;
 82     end;
 83     down(now);
 84     mid:=(tree[now].x+tree[now].y)>>1;
 85     if fx<=mid then
 86         insert(tree[now].left,color);
 87     if fy>mid then
 88         insert(tree[now].right,color);
 89     if tree[tree[now].left].cm<>tree[tree[now].right].cm then
 90         tree[now].cm:=2
 91     else
 92         tree[now].cm:=tree[tree[now].left].cm;
 93 end; { insect }
 94 procedure change(now:longint);
 95 var
 96     mid:longint;
 97 begin
 98     if (fx<=tree[now].x)and(tree[now].y<=fy) then
 99     begin
100         if tree[now].cm<>2 then
101             tree[now].cm:=1-tree[now].cm
102         else
103             tree[now].xm:=1-tree[now].xm;
104         exit;
105     end;
106     down(now);
107     mid:=(tree[now].x+tree[now].y)>>1;
108     if fx<=mid then
109         change(tree[now].left);
110     if fy>mid then
111         change(tree[now].right);
112     if tree[tree[now].left].cm<>tree[tree[now].right].cm then
113         tree[now].cm:=2
114     else
115         tree[now].cm:=tree[tree[now].left].cm;
116 end;{ change }
117 function make(s:ansistring):node2;
118 var
119     ch1,ch2:char;
120 begin
121     while pos(' ',s)>0 do
122      delete(s,pos(' ',s),1);
123     ch1:=s[1];
124     ch2:=s[length(s)];
125     delete(s,1,1);
126     delete(s,length(s),1);
127     val(copy(s,1,pos(',',s)-1),make.x);
128     delete(s,1,pos(',',s));
129     val(s,make.y);
130     make.x:=make.x*2;
131     make.y:=make.y*2;
132     if ch1='(' then
133         inc(make.x);
134     if ch2=')' then
135         dec(make.y);
136 end;{ make }
137 procedure solve();
138 var
139     state:node2;
140     ch   :char;
141     sx   :ansistring;
142 begin
143     tot:=0;
144     number1:=0;
145     number2:=0;
146     fillchar(tree,sizeof(tree),0);
147     build(0,oo);
148     while not eof do
149     begin
150         read(ch);
151         readln(sx);
152         state:=make(sx);
153         if (state.x>state.y) then
154         begin
155             if (ch='I')or(ch='C')and(state.x*state.y>0) then
156             begin
157                 fx:=0;
158                 fy:=oo;
159                 insert(1,0);
160             end
161             else
162                 continue;
163         end;
164         fx:=state.x;
165         fy:=state.y;
166         case ch of 
167           'U':insert(1,1);
168           'I':begin
169                 fx:=0;
170                 fy:=state.x-1;
171                 if fx<=fy then
172                     insert(1,0);
173                 fx:=state.y+1;
174                 fy:=oo;
175                 if fx<=fy then
176                     insert(1,0);
177             end;
178           'D':insert(1,0);
179           'C':begin
180                 fx:=0;
181                 fy:=state.x-1;
182                 if fx<=fy then
183                     insert(1,0);
184                 fx:=state.y+1;
185                 fy:=oo;
186                 if fx<=fy then
187                     insert(1,0);
188                 fx:=state.x;
189                 fy:=state.y;
190                 change(1);
191             end;
192           'S':change(1);
193         end;
194     end;
195 end; { solve }
196 procedure calc(now:longint);
197 begin
198     if now=0 then
199         exit;
200     if tree[now].cm=1 then
201     begin
202         inc(number1);
203         answer1[number1].x:=tree[now].x;
204         answer1[number1].y:=tree[now].y;
205         exit;
206     end;
207     down(now);
208     calc(tree[now].left);
209     calc(tree[now].right);
210 end;{ calc }
211 procedure merge();
212 var
213     i:longint;
214 begin
215     number2:=1;
216     answer2[1].x:=answer1[1].x;
217     answer2[1].y:=answer1[1].y;
218     for i:=1 to number1-1 do
219         if (answer1[i+1].y>answer2[number2].y)and(answer1[i+1].x<=answer2[number2].y+1) then
220             answer2[number2].y:=answer1[i+1].y
221         else
222             if answer1[i+1].x>answer2[number2].y+1 then
223             begin
224                 inc(number2);
225                 answer2[number2].x:=answer1[i+1].x;
226                 answer2[number2].y:=answer1[i+1].y;
227             end;
228 end;{ merge }
229 procedure print;
230 var
231     i:longint;
232 begin
233     for i:=1 to number2 do
234     begin
235         if odd(answer2[i].x) then
236             write('(')
237         else
238             write('[');
239         write(answer2[i].x>>1);
240         write(',');
241         write((answer2[i].y+1)>>1);
242         if odd(answer2[i].y) then
243             write(')')
244         else
245             write(']');
246         if i<>number2 then
247             write(' ');
248     end;
249 end;{ print }
250 begin
251     assign(input,'interval.in');reset(input);
252     assign(output,'interval.out');rewrite(output);
253     solve();
254     calc(1);
255     if number1=0 then
256         writeln('empty set')
257     else
258     begin
259         merge();
260         print();
261     end;
262     close(input);
263     close(output);
264 end.
posted @ 2012-04-18 19:09  Codinginging  阅读(244)  评论(0编辑  收藏  举报