POJ 2777
题目大意:有len个区间,每次为[x,y]区间上色,然后有询问操作,问[x,y]区间上有多少种颜色。
解:线段树维护,1wa是因为没看见x可以大于y并作出相应处理然后2wa3wa就是细节问题了,大体是l,r和s,e混淆。然后tle,是因为lazy写错了,正解应该是如果包含则直接改值,当以后如果在改的区间内,这个区间只有一个颜色的话,记得把原来的颜色递归给儿子,把c置0再递归处理(因为区间的划分决定了你目前所在的区间一定包含我们要涂改的区间的子区间,如果这个区间只有一个颜色那么新的子区间的插入就会改变这个情况,所以lazy标记置0,并一定要把原来的颜色递归下去!不然对这些子区间的询问会出错。
View Code
1 //poj 2777
2 const
3 maxl=101111;
4 maxt=31;
5 inf='1.txt';
6 type
7 data=record
8 mid, l, r, st, ed, c: longint;
9 end;
10 var
11 tree: array[0..maxl*4]of data;
12 col: array[0..maxt]of boolean;
13 ans, len, t, o: longint;
14 procedure build(const s, e, k, color: longint);
15 begin
16 with tree[k] do begin
17 st := s; ed := e; c := color;
18 mid := (st+ed)>>1;
19 if s=e then exit;
20 l := k << 1; build(s, mid, l, color);
21 r := l + 1; build(mid+1, e, r, color);
22 end;
23 end;
24
25 procedure init;
26 begin
27 readln(len, t, o);
28 build(1, len, 1, 1);
29 end;
30
31 procedure cover(const s, e, k, color: longint);
32 begin
33 with tree[k] do begin
34 if (s<=st)and(ed<=e) then begin
35 c := color; exit;
36 end;
37 if c>0 then begin
38 tree[l].c := c; tree[r].c := c;
39 c := 0; //!!!
40 end;
41 if s<=mid then cover(s, e, l, color);
42 if e>mid then cover(s, e, r, color);
43 end;
44 end;
45
46 procedure count(const s, e, k: longint);
47 begin
48 with tree[k] do begin
49 if c>0 then begin
50 col[c] := true; exit;
51 end;
52 if s<=mid then count(s, e, l);
53 if e>mid then count(s, e, r);
54 end;
55 end;
56
57 procedure main;
58 var
59 i, j, x, y, z: longint;
60 c: char;
61 begin
62 for i := 1 to o do begin
63 read(c);
64 if c='C' then begin
65 readln(x, y, z);
66 if x>y then begin
67 j := x; x := y; y := j;
68 end;
69 cover(x, y, 1, z);
70 end
71 else begin
72 fillchar(col, sizeof(col), 0);
73 readln(x, y);
74 if x>y then begin
75 j := x; x := y; y := j;
76 end;
77 count(x, y, 1);
78 ans := 0;
79 for j := 1 to t do
80 if col[j] then inc(ans);
81 writeln(ans);
82 end;
83 end;
84 end;
85
86 begin
87 assign(input,inf); reset(input);
88 init;
89 main;
90 end.