题目:《中学高级本(教材)》P168
解题思路:
本题是一道统计题。乍看此题,并不感觉很难,但实际做起来有一定的难度。
使用线段树,维护区间的最大值(这里的最大值不同于一般的最大值),并进行统计即可。
代码如下:
program railway;
type
node=record
v,cover:longint;
s,e:longint;
l,r:longint;
end;
var
c,s,r,tot:longint;
tree:array[0..200000]of node;
function max(x,y:longint):longint;
begin
if x>y then exit(x)
else exit(y);
end;
procedure build(s,e:longint);
var
v,mid:longint;
begin
inc(tot);
v:=tot;
tree[v].s:=s;
tree[v].e:=e;
mid:=(s+e)shr 1;
if s<e then
begin
tree[v].l:=tot+1;
build(s,mid);
tree[v].r:=tot+1;
build(mid+1,e);
end;
end;
function find(now,s,e,h,re:longint):boolean;
var
mid:longint;
t1,t2:boolean;
begin
if tree[now].s=tree[now].e then
begin
if re-tree[now].v>=h then exit(true)
else exit(false);
end;
if re-tree[now].v>=h then exit(true);
mid:=(tree[now].s+tree[now].e)shr 1;
if e<=mid then exit(find(tree[now].l,s,e,h,re-tree[now].cover));
if s>mid then exit(find(tree[now].r,s,e,h,re-tree[now].cover));
exit(find(tree[now].l,s,e,h,re-tree[now].cover)
and find(tree[now].r,s,e,h,re-tree[now].cover));
end;
procedure insert(now,s,e,h:longint);
var
mid:longint;
begin
if (s<=tree[now].s)and(tree[now].e<=e)then
begin
inc(tree[now].cover,h);
inc(tree[now].v,h);
exit;
end;
mid:=(tree[now].s+tree[now].e)shr 1;
if e<=mid then insert(tree[now].l,s,e,h)
else
begin
if s>mid then insert(tree[now].r,s,e,h)
else
begin
insert(tree[now].l,s,e,h);
insert(tree[now].r,s,e,h);
end;
end;
tree[now].v:=max(tree[tree[now].l].v,tree[tree[now].r].v)+tree[now].cover;
end;
procedure work;
var
i,x,y,h:longint;
begin
readln(c,s,r);
tot:=0;
build(1,c);
for i:=1 to r do
begin
readln(x,y,h);
if find(1,x,y-1,h,s) then
begin
insert(1,x,y-1,h);
writeln('YES');
end
else writeln('NO');
end;
end;
begin
assign(input,'railway.in');
assign(output,'railway.out');
reset(input);
rewrite(output);
work;
close(input);
close(output);
end.