SDOI2015 道路修建

2021-09-27 07:32:58 字數 2317 閱讀 3517

傳送門

線段樹維護最小生成樹。兩個結點合併就是把兩個結點之間的兩條橫邊加上後形成乙個環,然後剪掉環上的最大值即可得到當前最小生成樹。(不會證)

於是現在只需要考慮怎麼找最大值。

首先這個環一定是如下構成:兩邊是左節點的最右豎邊和右節點的最左豎邊,然後中間是所有的上下兩行橫邊。如下圖紅色部分。

那麼發現維護每個節點的最右(左)豎邊及其右(左)邊的最大值即可。

然而,如果左邊只剩下了一條豎邊,而最大值又恰巧是這條邊,那麼刪去這條邊之後,左邊就只剩下了橫邊,新節點的左右豎邊就要用右節點的豎邊更新。同時,我們還要找左節點的橫邊中的最大值,來更新新節點的最左豎邊及其左邊最大值。右邊只剩一條邊的情況同理。

總之,要分類討論一些東西,草稿紙上畫一畫就很明白了。

整理一下,每個節點維護的是它所對應區間的最小生成樹的資訊,維護的東西如下:

l /r

:l/r:

l/r:

節點在序列中的左右端點位置。

l _v

al/r

_val

:l\_val/r\_val:

l_val/

r_va

l:節點的最左/右豎邊權值。

r ow

_max

:row\_max:

row_ma

x:節點中橫邊的最大值。

c nt

:cnt:

cnt:

節點中豎邊個數(特判上述特殊情況用)

l _m

ax/r

_max

:l\_max/r\_max:

l_max/

r_ma

x:節點中最左/右豎邊及其左/右邊部分所有邊權的最大值。

s um

:sum:

sum:

節點維護的最小生成樹的邊權和。

注意這裡我記錄的行是0

00和1

11,輸入的行是1

11和2

22,要記得減一…

#include

#define lc (root<<1)

#define rc (root<<1|1)

#define mid (t[root].l+t[root].r>>1)

using

namespace std;

const

int maxn=

6e4+10;

int n,m,row[2]

[maxn]

,clm[maxn]

;int xa,ya,xb,yb,w,l,r;

char op[10]

;struct node

friend

inline node operator+(

const node &l,

const node &r)

}else

if(r.l_val==del)

}return ret;

}}t[maxn<<2]

;inline

void

build

(int root,

int l,

int r)

inline

void

update_clm

(int root,

int pos)

//pos:(h,pos)->(h,pos+1)

inline

void

update_row

(int root,

int pos)

if(pos<=mid)

update_row

(lc,pos)

;else

update_row

(rc,pos)

; t[root]

=t[lc]

+t[rc];}

inline node query

(int root,

int l,

int r)

inline

intread()

intmain()

}if(op[0]

=='q'

) l=

read()

,r=read()

,printf

("%d\n"

,query(1

,l,r)

.sum);}

}

SDOI2015 道路修建

description 某國有2n個城市,這2n個城市構成了乙個2行n列的方格網。現在該國 有乙個旅遊發展計畫,這個計畫需要選定l r兩列 l r 修建若干條專用道路,使得這兩列之間 包括這兩列 的所有2 r l 1 個城市中每個城市可以只通過專用道路就可以到達這2 r l 1 個城市中的任何乙個城...

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

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

bzoj3995 SDOI2015 道路修建

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