東東的高速之旅 (線段樹維護區間最小值)(模擬賽)

東東的高速之旅(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.
發佈了33 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章