HDU5023(A Corrupt Mayor’s Performance Art)(pascal!!!)
http://acm.hdu.edu.cn/showproblem.php?pid=5023(题目)
题目大意
有n个数,m次操作,P操作是肮脏的市长对墙做肮脏的行为,把墙从a到b染成肮脏的颜色c,Q操作是询问有多少种肮脏的颜色在a和b之间。
题解
开始我觉得可以写三十棵线段树,然后好不容易写出来了结果空间爆了,果然这种弱智的做法还是不可以,然后,我开始认真的思考,觉得可以用压位来维护线段树中父亲节点的包含颜色,接着,多调试几遍就过了。这道题目唯一的难点就是行末一定不能有空格。
var
x,y:array[0..4200000]of longint;
n,m,i,j,k,a,b,c,res,p:longint;
s:char;
procedure pushup(k:longint);
begin
x[k]:=x[k*2] or x[k*2+1];
end;
procedure pushdown( k:longint);
var
lc,rc:longint;
begin
if(y[k]<>0)then
begin
lc:=k*2;
rc:=k*2+1;
y[lc]:=y[k];
y[rc]:=y[k];
x[lc]:=y[k];
x[rc]:=y[k];
y[k]:=0;
end;
end;
procedure update(k,l,r:longint);
var
lc,rc,mid:longint;
begin
lc:=k*2;
rc:=k*2+1;
if(a<=l)and(r<=b)then
begin
y[k]:=1 shl (c-1);
x[k]:=1 shl (c-1);
exit;
end;
pushdown(k);
mid:=(l+r)div 2;
if(a<=mid)then update(lc,l,mid);
if(b>mid)then update(rc,mid+1,r);
pushup(k);
end;
function query(k,l,r:longint):longint;
var
res,mid:longint;
begin
if(a<=l)and(r<=b)then exit(x[k]);
pushdown(k);
res:=0;
mid:=(l+r)div 2;
if a<=mid then
res:=res or query(k*2,l,mid);
if b>mid then
res:=res or query(k*2+1,mid+1,r);
exit(res);
end;
procedure build(k,l,r:longint);
var
mid:longint;
begin
y[k]:=0;
if(l=r)then
begin
x[k]:=2;
exit;
end;
mid:=(l+r)div 2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
pushup(k);
end;
begin
n:=1;
while(n<>0)or(m<>0)do
begin
readln(n,m);
if(n=0)and(m=0)then halt;
build(1,1,n);
for m:=1 to m do
begin
read(s);
if s='P' then
begin
read(a,b,c);
update(1,1,n);
end
else
begin
read(a,b);
p:=0;
res:=query(1,1,n);
for i:=1 to 30 do
begin
if(res and(1 shl(i-1))<>0)then
begin
if p=0 then
write(i)
else write(' ',i);
p:=1;
end;
end;
writeln;
end;
readln;
end;
end;
end.