SSL P2645 线段树练习题二

    xiaoxiao2021-04-16  33

    题目大意: N长度的桌子上零散地放着M个不同颜色的盒子,桌子的后方是一堵墙。给出每个箱子的左端跟右端,问从桌子前方可以看到多少个盒子?假设人站得足够远(输入时,由底向上,从左到右)。

    1<=n<=100000,1<=m<=100000,保证坐标[l,r]范围为[1,n]. 题解: 线段树: 跟ZJU的那道题一样, http://blog.csdn.net/gx_man_vip/article/details/70160195 不过把记录数量变成了记录是否存在。

    var ans,tree:array [0..300000] of longint; sum,i,n,m,a,b,c:longint; procedure insert(p,l,r,a,b:longint); var mid:longint; begin mid:=(l+r) div 2; if (a=l) and (b=r) then tree[p]:=c else begin if tree[p]<>-1 then begin tree[p * 2]:=tree[p]; tree[p*2+1]:=tree[p]; tree[p]:=-1; end; if b<=mid then insert(p*2,l,mid,a,b) else if a>=mid then insert(p*2+1,mid,r,a,b) else begin insert(p * 2,l,mid,a,mid); insert(p*2+1,mid,r,mid,b); end; end; end; procedure count(p,l,r:longint); var mid:longint; begin mid:=(l+r) div 2; if tree[p]=-2 then begin c:=-2; exit; end else if (tree[p]<>c) and (tree[p]<>-1) then begin c:=tree[p]; ans[c]:=1; end else if (r-l=1) and (c=tree[p]) then exit else if tree[p]=-1 then begin count(p * 2,l,mid); count(p*2+1,mid,r); end; end; procedure print; begin for i:=1 to n do if ans[i]=1 then inc(sum); writeln(sum); end; begin for i:=0 to 300000 do tree[i]:=-2; readln(n); readln(m); for i:=1 to m do begin readln(a,b); c:=i; insert(1,1,n,a,b); end; c:=-3; count(1,1,n); print; end.
    转载请注明原文地址: https://ju.6miu.com/read-673167.html

    最新回复(0)