东东的高速之旅(highway.pas/.c/.cpp)
题目描述
一天东东爸 带东东回老家,开车行驶在宽阔的高速公路上。东东思维本来就发散,让他无聊的坐几个小时他一定会无聊的。所以东东爸 就给他准备一道有关高速公路的问题,让他在无聊的旅途中平添些乐趣。
题目是这样的:行驶在高速上的车辆会对高速造成一定的损伤。假设一条高速公路被收费站分成了若干段,整条高速公路有一个耐久度W。如果一辆汽车从s到t,s到t之间的高速公路的耐久度就会减少d。一旦某段公路的耐久度小于或等于0,这段公路就会永久性地毁坏,任何汽车也就无法通过已经毁坏的地方。
有一种维护车从s到t,可以将途中高速公路的耐久度增加r,并且不会造成公路耐久度的降低。虽然有维护车的存在,但是已经毁坏的某段路仍然无法修复。
东东的任务就是统计一下一共有多少辆汽车可以成功通行。
东东拿到题目,异常兴奋,争取在下高速的时候得到答案。但是题目真的太难了,快下高速了,东东还是没有得到结果,急的满头大汗,就给你打了电话,你能帮东东得到正确的结果么?
输入格式
第一行是三个正整数N、M和W。表示高速公路被分成了N段,有M辆车依次通过,整段高速公路的初始的耐久度为W。
以下M行每行描述一辆车,格式如下:
1 s t d:一辆汽车准备通过区间[s,t]。如果区间[s,t]里面有任何一个地方损毁了,这辆汽车就会取消整个通行计划;否则这辆汽车就可以成功通过区间[s,t],并且使这个区间的耐久度减少d。即使通过之后会把某些地方毁坏了也是能够通过的。
2 s t r:一辆维修车通过区间[s,t],为这段公路的耐久度增加r。如果区间[s,t]里面有任何一个地方损毁了,这辆维修车也会取消整个通行计划。
其中对于所有的区间[s,t]:表示从第s段的开始,到达第t段的结尾。
输出格式
输出一个数,表示有多少汽车可以成功通行。
样例输入
3 4 2
2 1 3 3
1 1 2 3
1 2 3 2
1 1 3 1
样例输出
3
数据范围与约定
对于30%的数据 N,M <= 100
对于50%的数据 N,M <= 1000
对于100%的数据 N,M<= 100000
1≤W≤1000,1≤s≤t≤N,1≤d≤1000,1≤r≤1000
本题用lazy标记的线段树去维护数据,即可。需要注意的是维护车辆也是汽车,也要统计到答案中。
program mys;
type
ab=record
l,r,w,c:longint;
end;
var n,m,e,z,s,t,p,i,tot,ans,sum:longint;
f:array[0..1000000]of ab;
procedure built(x,y,i:longint);
var mid:longint;
begin
f[i].l:=x;
f[i].r:=y;
if x=y then
begin
f[i].w:=e;
exit;
end;
mid:=(x+y)div 2;
built(x,mid,i*2);
built(mid+1,y,i*2+1);
if f[i*2].w<=f[i*2+1].w then
f[i].w:=f[i*2].w
else
f[i].w:=f[i*2+1].w;
end;
function pd(x,y,k:longint):boolean;
var mid:longint;
begin
if (f[k].l=x)and(f[k].r=y) then
begin
if f[k].c<>0 then
begin
f[k*2].w:=f[k*2].w-f[k].c;
f[k*2].c:=f[k*2].c+f[k].c;
f[k*2+1].w:=f[k*2+1].w-f[k].c;
f[k*2+1].c:=f[k*2+1].c+f[k].c;
f[k].c:=0;
end;
if f[k].w<=0 then exit(false)
else
exit(true);
end;
if f[k].c<>0 then
begin
f[k*2].w:=f[k*2].w-f[k].c;
f[k*2].c:=f[k*2].c+f[k].c;
f[k*2+1].w:=f[k*2+1].w-f[k].c;
f[k*2+1].c:=f[k*2+1].c+f[k].c;
f[k].c:=0;
end;
mid:=(f[k].l+f[k].r)div 2;
if y<=mid then exit(pd(x,y,k*2))
else if x>mid then exit(pd(x,y,k*2+1))
else
begin
if pd(x,mid,k*2) and pd(mid+1,y,k*2+1) then
exit(true)
else
exit(false);
end;
if f[k*2].w<=f[k*2+1].w then
f[k].w:=f[k*2].w
else
f[k].w:=f[k*2+1].w;
end;
procedure change(x,y,k:longint);
var mid:longint;
begin
if (f[k].l=x)and(f[k].r=y) then
begin
if f[k].c<>0 then
begin
f[k*2].w:=f[k*2].w-f[k].c;
f[k*2].c:=f[k*2].c+f[k].c;
f[k*2+1].w:=f[k*2+1].w-f[k].c;
f[k*2+1].c:=f[k*2+1].c+f[k].c;
f[k].c:=0;
end;
f[k].w:=f[k].w-p;
f[k].c:=f[k].c+p;
exit;
end;
if f[k].c<>0 then
begin
f[k*2].w:=f[k*2].w-f[k].c;
f[k*2].c:=f[k*2].c+f[k].c;
f[k*2+1].w:=f[k*2+1].w-f[k].c;
f[k*2+1].c:=f[k*2+1].c+f[k].c;
f[k].c:=0;
end;
mid:=(f[k].l+f[k].r)div 2;
if y<=mid then change(x,y,k*2)
else if x>mid then change(x,y,k*2+1)
else
begin
change(x,mid,k*2);
change(mid+1,y,k*2+1);
end;
if f[k*2].w<=f[k*2+1].w then
f[k].w:=f[k*2].w
else
f[k].w:=f[k*2+1].w;
end;
begin
assign(input,'highway.in');reset(input);
assign(output,'highway.out');rewrite(output);
readln(n,m,e);
built(1,n,1);
ans:=0;
for i:=1 to m do
begin
readln(z,s,t,p);
if z=2 then p:=-p;
if pd(s,t,1) then
begin
inc(ans);
change(s,t,1);
end;
end;
writeln(ans);
close(input);
close(output);
end.