Yallisha的画
题目描述:
Yallisha很喜欢画图,特别是在电脑上画图。但是,在上色是一件很麻烦的事情,因此Yallisha决定编写一个软件来完成这个工作。
可惜,能力所限,软件最困难的部分她无法完成,因此她找到了你,希望你能帮助她完成这个工作。
为了简化问题,Yallisha把一幅图拉制成一条线。
Yallisha会给出很多指令,包括告诉你她把某个区间染成了某种颜色,和请你反馈在某个区间中有多少种颜色(她不希望她的画颜色太杂。)初始时,颜色为1。
输入格式:
输入文件的第一行为两个整数n,m,表示线的长度和指令的个数。
接下来m行,每行的第一个整数为1或2。如果是1,则后面跟着两个整数a,b,表示需要你反馈[a,b]中有多少中颜色。如果是2,则后面跟着三个整数a,b,c,表示她把[a,b]染成了颜色C。
输出格式:
对于每次询问,返回区间中的颜色数。
输入样例:
5 3
1 1 3
2 1 3 2
1 2 4
输出样例:
1
2
数据范围:
对于50%的数据,1<=n<=100,1<=m<=100
对于80%的数据,1<=n<=100,000,1<=m<=100,000
对于100%的数据,1<=n<=1,000,000,1<=m<=1,000,000,1<=Co<=30
程序:
Program Picture_Mpq;
type data=record
sum:longint;
cover:integer;
end;
Const Maxn=1 shl (trunc(ln(1000000)/ln(2))+2);
var
n,m,co,left,right:longint;
tree:array[1..Maxn] of data;
procedure init;
begin
readln(n,m);
tree[1].sum:=1;
tree[1].cover:=1;
end;
procedure Change(x,y,len:longint);
var
m:longint;
begin
if (x>right) or (left>y) then exit;
if (x>=left) and (right>=y) then
begin
tree[len].sum:=co;
tree[len].cover:=1;
exit;
end;
if tree[len].cover<>0 then
begin
tree[len].cover:=0;
tree[len*2].sum:=tree[len].sum;
tree[len*2].cover:=1;
tree[len*2+1].sum:=tree[len].sum;
tree[len*2+1].cover:=1;
end;
m:=(x+y) div 2;
Change(x,m,len*2);
Change(m+1,y,len*2+1);
tree[len].sum:=tree[len*2].sum or tree[len*2+1].sum;
end;
function Count(x,y,len:longint):longint;
var
m,tmp1,tmp2:longint;
begin
if (x>right) or (left>y) then exit(0);
if (tree[len].cover=1) or ((x>=left) and (right>=y)) then exit(tree[len].sum);
m:=(x+y) div 2;
tmp1:=Count(x,m,len*2);
tmp2:=Count(m+1,y,len*2+1);
exit(tmp1 or tmp2);
end;
procedure Main;
var
i,ch,ans,sum:longint;
begin
for i:=1 to m do
begin
read(ch);
if ch=2 then
begin
readln(left,right,co);
co:=1 shl (co-1);
Change(1,n,1);
end else
begin
readln(left,right);
ans:=Count(1,n,1);
sum:=0;
while ans<>0 do
begin
if ans mod 2=1 then inc(sum);
ans:=ans div 2;
end;
writeln(sum);
end;
end;
end;
begin
assign(input,'picture.in'); reset(input);
assign(output,'picture.out'); rewrite(output);
init;
Main;
close(input); close(output);
end.