您的位置:首页 > Web前端

[BZOJ1651] [Usaco2006 Feb]Stall Reservations 专用牛棚

2015-10-14 19:28 417 查看

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=1651

题目大意

给出奶牛运动的时间段,询问同一时间最多的奶牛数

题解

线段树或差分序列

线段树

var
x:array[0..3000000,1..4]of longint;
i,j,k:longint;
n,a,b,m:longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;

procedure build(a,l,r:longint);
var mid:longint;
begin
x[a,1]:=l; x[a,2]:=r;
if l=r then exit;
mid:=(l+r)>>1;
build(a*2,l,mid);
build(a*2+1,mid+1,r);
end;

procedure pushdown(a:longint);
begin
if x[a,1]=x[a,2] then begin x[a,4]:=0; exit; end;
inc(x[a*2,3],x[a,4]); inc(x[a*2,4],x[a,4]);
inc(x[a*2+1,3],x[a,4]); inc(x[a*2+1,4],x[a,4]);
x[a,4]:=0;
end;

procedure update(a,l,r:longint);
var mid:longint;
begin
if x[a,4]<>0 then pushdown(a);
if (l=x[a,1])and(r=x[a,2]) then begin inc(x[a,3]); inc(x[a,4]); exit; end;
mid:=(x[a,1]+x[a,2])>>1;
if r<=mid then update(a*2,l,r) else
if l>mid then update(a*2+1,l,r)
else begin update(a*2,l,mid); update(a*2+1,mid+1,r); end;
x[a,3]:=max(x[a*2,3],x[a*2+1,3]);
end;

begin
readln(n);
build(1,1,1000000);
for i:=1 to n do
begin
readln(a,b);
update(1,a,b);
end;
writeln(x[1,3]);
end.


差分序列

学习了一下~

差分是相邻两个数的差值,序列是所有的差值排成序列

我们考虑区间加上一个相同的数a,[L,R],那么对于差分序列x[l]+a,x[r+1]-a

最后用前缀和判断最大值即可

var
sum,x:array[0..1000005]of longint;
i,j,k:longint;
n,a,b,ans:longint;
begin
fillchar(x,sizeof(x),0);
fillchar(sum,sizeof(sum),0);
readln(n);
for i:=1 to n do
begin
readln(a,b);
inc(x[a]); dec(x[b+1]);
end;
ans:=0;
for i:=1 to 1000005 do
begin
sum[i]:=sum[i-1]+x[i];
if ans<sum[i] then ans:=sum[i];
end;
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: