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.