SDOI2015 道路修建

2022-08-25 22:39:24 字數 2675 閱讀 8128

description

某國有2n個城市,這2n個城市構成了乙個2行n列的方格網。現在該國**有乙個旅遊發展計畫,這個計畫需要選定l、r兩列(l<=r),修建若干條專用道路,使得這兩列之間(包括這兩列)的所有2(r-l+1)個城市中每個城市可以只通過專用道路就可以到達這2(r-l+1)個城市中的任何乙個城市。這種專用道路只能在同一行相鄰兩列的城市或者同一列的兩個城市之間修建,且修建需要花費一定的費用。由於該國**決定盡量縮減開支,因此**決定,選定l、r後,只修建2(r-l+1)-1條專用道路,使得這些專用道路構成乙個樹結構。現在你需要幫助該國**寫乙個程式,完成這個任務。具體地,該任務包含m個操作,每個操作的格式如下:

1、c x0 y0 x1 y1 w:由於重新對第x0行第y0列的城市和第x1行第y1列的城市之間的情況進行了考察,它們之間修建一條專用道路的花費變成了w;

2、q l r:若**選定的兩列分別為l、r,詢問**的最小開支。

input

第一行,兩個整數n、m。

第二行,n-1個整數,其中第i個整數表示初始時第1行第i列的城市和第1行第i+1列的城市之間修建一條專用道路的費用。

第三行,n-1個整數,其中第i個整數表示初始時第2行第i列的城市和第2行第i+1列的城市之間修建一條專用道路的費用。

第四行,n個整數,其中第i個整數表示初始時第1行第i列的城市和第2行第i列的城市之間修建一條專用道路的費用。

接下來的m行,每行乙個操作。

output

對於每個詢問操作,輸出一行,表示你計算出的**的最小開支。

sample input

3 3

1 22 1

3 1 2

q 1 3

c 1 2 2 2 3

q 2 3

sample output

7

5

data constraint

對於40%的資料,1<=n, m<=600;

對於全部的資料,1<=n, m<=60000,任何時刻任何一條專用道路的修建費用不超過104。

解法:用線段樹維護區間內的mst

具體合併方法如下:

首先,由於兩個都是樹結構,我們把區間間的兩條邊連起來,會出現乙個環,我們只需要把環上最長的邊cut掉即可

首先,綠色部分可以o(1)計算,我們需要維護的只是紅色和藍色部分,即區間內最左和最右的豎邊,以及其左/右橫邊的max .

如果我們cut的是是橫邊,或者雖然cut了豎邊但區間內有多條豎邊(cut藍色邊),那麼大區間的lc(最左豎邊再左邊橫框的max,即藍色部分),rc(紅色部分)都可以直接用兩個小區間的lc,rc更新。

但是如果我們cut的豎邊是區間內唯一的豎邊,如紅色邊,那麼我們新區間的lc需用藍,綠,以及左邊橫邊的max更新,由於左邊區間只有一條豎邊,那麼該區間的lc,rc即囊括了所有橫邊,直接用其來更新即可

右邊同理。

end.

#include#include

#include

#include

#include

using

namespace

std;

struct

treetr[

300011

];int a[60011],b[60011],c[60011

];int

n,m,i,sx,sy,tx,ty,w,ans,l,r;

tree tr;

char s[11

];tree merge(tree a,tree b,

intr)

cut=true

; }

if(mx==b.lef)

cut=true

; }

c.dn=a.dn+b.dn;

if(cut)c.dn--;

c.sum=a.sum+b.sum+a[r]+b[r]-mx;

if(pw==false

)

else

if(kd==1

)

else

returnc;}

void build(int l,int r,int

t)

intmid;

mid=(l+r)/2

; build(l,mid,t+t);

build(mid+1,r,t+t+1

); tr[t]=merge(tr[t+t],tr[t+t+1

],mid);

}void insert(int t,int l,int r,int

x)

intmid;

mid=(l+r)/2

;

if(x<=mid)insert(t+t,l,mid,x);

if(x>mid)insert(t+t+1,mid+1

,r,x);

tr[t]=merge(tr[t+t],tr[t+t+1

],mid);

}tree ask(

int t,int l,int r,int x,int

y)int

main()

insert(

1,1,n,sy);

}else}}

SDOI2015 道路修建

傳送門 線段樹維護最小生成樹。兩個結點合併就是把兩個結點之間的兩條橫邊加上後形成乙個環,然後剪掉環上的最大值即可得到當前最小生成樹。不會證 於是現在只需要考慮怎麼找最大值。首先這個環一定是如下構成 兩邊是左節點的最右豎邊和右節點的最左豎邊,然後中間是所有的上下兩行橫邊。如下圖紅色部分。那麼發現維護每...

SDOI2015 道路修建(線段樹維護連通性)

這道題可以看做是 shoi2008 堵塞的交通的加強版,由於形同模擬不同人的寫法差別很大,強烈建議理解了原理之後自己獨立寫 給乙個 2 m 的網格圖,每次操作支援修改一條邊的權值,和查詢 l,r 含 的最小生成樹 如果做過上面那道題就很容易知道這道題是考 毒瘤的 線段樹 只需要維護8個標記 因寫法而...

bzoj3995 SDOI2015 道路修建

題目鏈結 分析 曲神的題解 曲神表示想要結構體版本的 題解最後給出的就是結構體的 bzoj1018的高階版 一開始看到這道題 好像不是很難,用線段樹維護最小生成樹 update的時候直接判斷上下哪一條橫邊比較小,連線即可 然而一下就發現了bug 存在可能性連線點的上下兩條邊都需要連線 那我們就要深入...