染色种数
http://luo.hustoj.com/problem.php?id=1105
var
n,m,i,j,k,l,x,y,z,cc:
longint
;
p:
Array
[
0..1000005
]
of
longint
;
c:
char
;
procedure
build(t,l,r:
longint
);
var
mid:
longint
;
begin
if
l=r
then
begin
p[t]:=
1
;exit;
end
;
mid:=(l+r) >>
1
;
build(t <<
1
,l,mid);
build(t <<
1
+
1
,mid+
1
,r);
p[t]:=
1
;
end
;
function
lowbit(x:
longint
):
longint
;
begin
exit(x
and
(-x));
end
;
function
count(x:
longint
):
longint
;
begin
count:=
0
;
while
x>
0
do
begin
inc(count);x:=x-lowbit(x);
end
;
end
;
procedure
change(t,l,r,x,y,c:
longint
);
var
mid:
longint
;
begin
if
(l=x)
and
(r=y)
then
begin
p[t]:=
1
<< (c-
1
);exit;
end
;
mid:=(l+r) >>
1
;
if
count(p[t])=
1
then
begin
p[t <<
1
]:=p[t];p[t <<
1
+
1
]:=p[t];
end
;
if
mid>=y
then
change(t <<
1
,l,mid,x,y,c)
else
if
mid<x
then
change(t <<
1
+
1
,mid+
1
,r,x,y,c)
else
begin
change(t <<
1
,l,mid,x,mid,c);change(t <<
1
+
1
,mid+
1
,r,mid+
1
,y,c);
end
;
p[t]:=p[t <<
1
]
or
p[t <<
1
+
1
];
end
;
function
find(t,l,r,x,y:
longint
):
longint
;
var
mid:
longint
;
begin
if
(l=x)
and
(r=y)
then
exit(p[t]);
mid:=(l+r) >>
1
;
if
count(p[t])=
1
then
begin
p[t <<
1
]:=p[t];p[t <<
1
+
1
]:=p[t];
end
;
if
mid>=y
then
exit(find(t <<
1
,l,mid,x,y));
if
mid<x
then
exit(find(t <<
1
+
1
,mid+
1
,r,x,y));
exit(find(t <<
1
,l,mid,x,mid)
or
find(t <<
1
+
1
,mid+
1
,r,mid+
1
,y));
end
;
begin
readln(n,cc,m);
build(
1
,
1
,n);
for
i:=
1
to
m
do
begin
read(c);
if
c=
'C'
then
begin
readln(x,y,z);
change(
1
,
1
,n,x,y,z);
end
;
if
c=
'P'
then
begin
readln(x,y);
writeln
(count(find(
1
,
1
,n,x,y)));
end
;
end
;
end
.
201882做了一题线段树,区间覆盖的最小值,一开始这样打,觉得很对,却爆零。其实是数据很大,要开int64,并且不光数组要开,函数minmax里也要开