线段树的区间更新
Problem: 1823
Memory: 1644K
Time: 2938MS
program hotel;
const maxN=16000*4;
type rec = record
left,right,value,lm,rm,mark:longint; end; //lm表示从左开始最多连续多少个,lr同理
var
n,k,i,a,mem,l:longint;
tree:array[1..maxN]of rec;
function max(a,b:longint):longint;
begin
if a>b then max:=a
else max:=b;
end;
procedure buildtree(l,r,k:longint);
var mid:longint;
begin
tree[k].left:=l;
tree[k].right:=r;
tree[k].value:=r-l+1;
tree[k].lm:=r-l+1;
tree[k].rm:=r-l+1;
tree[k].mark:=-1;
if l=r then exit;
mid:=(l+r)div 2;
buildtree(l,mid,k*2);
if mid<r then
buildtree(mid+1,r,k*2+1);
end;
procedure pushdown(k:longint);
var t:longint;
begin
if tree[k].mark=-1 then exit; //-1表示已经更新完毕
if tree[k].mark=0 then begin
t:=tree[k*2].right-tree[k*2].left+1;
tree[k*2].value:=t;
tree[k*2].lm:=t;
tree[k*2].rm:=t;
tree[k*2].mark:=0;
t:=tree[k*2+1].right-tree[k*2+1].left+1;
tree[k*2+1].value:=t;
tree[k*2+1].lm:=t;
tree[k*2+1].rm:=t;
tree[k*2+1].mark:=0;
end
else begin
tree[k*2].value:=0;
tree[k*2].lm:=0;
tree[k*2].rm:=0;
tree[k*2].mark:=1;
tree[k*2+1].value:=0;
tree[k*2+1].lm:=0;
tree[k*2+1].rm:=0;
tree[k*2+1].mark:=1;
end;
tree[k].mark:=-1;
end;
procedure pushup(k:longint);
var a,b,c:longint;
begin
a:=tree[k*2].value;
b:=tree[k*2+1].value;
c:=tree[k*2].rm+tree[k*2+1].lm;
tree[k].value:=max(max(a,b),c);
tree[k].lm:=tree[k*2].lm;
tree[k].rm:=tree[k*2+1].rm;
if (tree[k*2].lm=(tree[k*2].right-tree[k*2].left+1)) then tree[k].lm:=tree[k].lm+tree[k*2+1].lm;
if (tree[k*2+1].rm=(tree[k*2+1].right-tree[k*2+1].left+1)) then tree[k].rm:=tree[k].rm+tree[k*2].rm;
end;
procedure update(l,r,w,k:longint);
begin
if (tree[k].left=l)and(tree[k].right=r) then begin
if w=1 then begin
tree[k].value:=0;
tree[k].mark:=1;
tree[k].lm:=0;
tree[k].rm:=0;
end
else if w=0 then begin
tree[k].value:=r-l+1;
tree[k].mark:=0;
tree[k].lm:=r-l+1;
tree[k].rm:=r-l+1;
end;
exit;
end;
pushdown(k);//更新子树
if tree[k*2].right>=r then
update(l,r,w,k*2)
else if tree[k*2+1].left<=l then update(l,r,w,k*2+1)
else begin
update(l,tree[k*2].right,w,k*2);
update(tree[k*2+1].left,r,w,k*2+1);
end;
pushup(k);//更新父节点值域
end;
begin
readln(n,k);
buildtree(1,n,1);
for i:=1 to k do begin
read(a);
if a=3 then writeln(tree[1].value)
else begin
readln(l,mem);
if a=1 then update(l,l+mem-1,1,1)
else update(l,l+mem-1,0,1);
end;
end;
end.
反思:
1.发现自己的分析能力还有很大上升空间…看其他人写题解什么的能把问题分析得清清楚楚的,我完全不知道怎么写题解…还是练习少了吧…
2.觉得代码还有可以简化的地方,继续加油

&spm=1001.2101.3001.5002&articleId=52761675&d=1&t=3&u=9580e77b447e4fb1b682c42da213b24e)
439

被折叠的 条评论
为什么被折叠?



