PKU 2777 线段树
http://hi.baidu.com/raulliubo/blog/item/24587160e34cff40eaf8f865.html
在众多大牛的指点下AC了。以前总WA竟然是因为数组开小了。。。这不应该是RE吗。。怎么WA了。抑郁了,还以为算法错了。这题考的就是线段树加二进制储存信息。。。。
my ugly code:
var
color, left, right : array[1 .. 1000000] of longint;
order : char;
i, count, temp, a, b, len, t, o, c : longint;
procedure buildtree(now, l, r : longint);
var
mid : longint;
begin
if l = r then begin
left[now] := l;
right[now] := r;
exit;
end;
left[now] := l;
right[now] := r;
mid := (left[now] + right[now]) shr 1;
buildtree(now * 2, l, mid);
buildtree(now * 2 + 1, mid+1, r);
end;
function single(x : longint) : boolean;
begin
exit((x - 1) and x = 0);
end;
procedure insert(now, l, r, co : longint);
var
mid : longint;
begin
if (l <= left[now]) and (r >= right[now]) then begin
color[now] := co;
exit;
end;
if color[now] = co then
exit;
if single(color[now]) then begin
color[2*now] := color[now];
color[2*now + 1] := color[now];
end;
mid := (left[now] + right[now]) shr 1;
if l <= mid then
insert(now * 2, l, r, co);
if r > mid then
insert(now * 2 + 1, l, r, co);
color[now] := color[now * 2] or color[now * 2 + 1];
end;
procedure search(now, l, r : longint);
var
mid : longint;
begin
if (l <= left[now]) and (r >= right[now]) then begin
count := count or color[now];
exit;
end;
if single(color[now]) then begin
count := count or color[now];
exit;
end;
mid := (left[now] + right[now]) shr 1;
if l <= mid then
search(now * 2, l, r);
if r > mid then
search(now * 2 + 1, l, r);
end;
function ans(c : longint) : longint;
var
i, cnt : longint;
begin
cnt := 0;
while c > 0 do begin
if c mod 2 = 1 then
inc(cnt);
c := c shr 1;
end;
exit(cnt);
end;
begin
readln(len, t, o);
buildtree(1, 1, len);
insert(1, 1, len, 1);
for i := 1 to o do begin
read(order);
case order of
'C' :
begin
readln(a, b, c);
if a > b then begin
temp := a;
a := b;
b := temp;
end;
insert(1, a, b, 1 shl (c-1));
end;
'P' :
begin
readln(a, b);
if a > b then begin
temp := a;
a := b;
b := temp;
end;
count := 0;
search(1, a, b);
writeln(ans(count));
end;
end;
end;
end.