bzoj3995 SDOI2015 道路修建

2021-08-15 11:10:52 字數 2822 閱讀 2908

題目鏈結

分析:

曲神的題解

(曲神表示想要結構體版本的**,題解最後給出的就是結構體的**)

bzoj1018的高階版

一開始看到這道題:好像不是很難,用線段樹維護最小生成樹

update的時候直接判斷上下哪一條橫邊比較小,連線即可

然而一下就發現了bug:

存在可能性連線點的上下兩條邊都需要連線

那我們就要深入討論

**中的區間劃分方式和平成不大一樣: [l

.r]−

−−>[l

.mid

]+[m

id,r

] [l.

r]−−

−>[l

.mid

]+[m

id,r

]之後的討論都是基於以上條件

這樣有乙個好處:

每個結點維護的是乙個2*2的小圖,方便處理線段樹結點中的資訊(之後會介紹)

當然樸素的線段樹那樣分割也是可以的

我們在update之前左右區間都是乙個完美的聯通塊如果出現了上述情況,連線上下的兩條邊後會出現環那我們就遵循最小生成樹的原則:刪除環上的最長邊然而這個刪除並沒有表面上(記錄最大值刪除)這麼簡單

(難道這就是墨菲定律的體現???)

試想如果我們在每乙個結點中記錄了乙個最大值,每次合併的時候刪除了,那我們去**找次大值作為下次刪除的邊呢

我們先來看個圖:

我們在合併左右區間的時候,如果得到環,那麼一定是上面標記出的最小環

所以我們需要刪除的邊一定在這個最小環上

怎麼確定這個環呢?

我們需要記錄每個結點中最靠左的豎線和最靠右的豎線:

顯然,最左豎線再往左的所有橫線一定都被選中

最有豎線再往右的所有橫線一定都被選中

在合併區間的時就可以用左區間的最右豎線和右區間的最左豎線確定這個環

那現在我們就需要在這個環上選一條邊刪掉:

這樣線段樹的結點中就需要維護一下幾個值:mx

m

x:區間最大邊權 ls

l

s:最靠左的豎線 rs

r

s:最靠右的豎線 lm

x lmx

:最靠左的豎線再往左的橫線中的最小邊權(方便查詢合併時查詢最小環中的最小邊權) rm

x rmx

:最靠右的豎線再往右的橫線中的最小邊權(方便查詢合併時查詢最小環中的最小邊權) su

m sum

:最小生成樹的權值和

維護的時候,當:l+

1=r l+1

=r,我們就單點插入

修改的時候,不管是橫線還是豎線,我們不用糾結到底這個修改在**,

因為修改一條邊會對整個區間都產生影響,所以直接:

change(bh<<1,l,mid,x,min(mid,y));

change(bh<<1|1,mid,r,max(x,mid+1),y);

經歷了乙個不短的wa過程

發現是在修改的時候v1,v2陣列改錯了。。。

詢問的時候,如果l=r,應該輸出豎線的值

線段樹的寫法有很多種,有時候可以考慮使每個最小結點維護乙個小區間

#include#include#includeusing namespace std;

const int n=100010;

struct node;

node t[n<<2];

int v1[n],v2[n],v[n],n,m;

node insert(int l,int r)

else

if (v[l]>v[r]) //選擇右邊的豎線

else

return ans;

}node update(node l,node r)

else

return ans;

}void build(int bh,int l,int r)

int mid=(l+r)>>1;

build(bh<<1,l,mid);

build(bh<<1|1,mid,r);

t[bh]=update(t[bh<<1],t[bh<<1|1]);

}node ask(int bh,int l,int r,int x,int y)

}void change(int bh,int l,int r,int x,int y)

int mid=(l+r)>>1;

change(bh<<1,l,mid,x,min(mid,y));

change(bh<<1|1,mid,r,max(x,mid),y);

t[bh]=update(t[bh<<1],t[bh<<1|1]);

}int main()

else v[ya]=z; //豎線

change(1,1,n,ya,yb);

}else

}return

0;}

bzoj3995 道路修建題解

前陣子本想一本正經的寫一篇關於字尾樹入門較為詳細的文章,由於博主又懶了,然後 今天覺得心情愉快,於是突發奇想,要更新一篇部落格,於是就有了這篇部落格 就是這樣。include cstdio include algorithm define maxn 60000 10 define ll long l...

Bzoj 2726 SDOI 任務安排

memory limit 131072kb 64bit io format lld llu description 機器上有n個需要處理的任務,它們構成了乙個序列。這些任務被標號為1到n,因此序列的排列為1,2,3.n。這n個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批加工...

BZOJ 3991 SDOI2015 尋寶遊戲

題目大意 給定一棵樹,其中有若干個關鍵點,任意選擇起點,求從起點出發訪問所有關鍵點又回到起點的最小邊權總和,有m個修改操作,每次修改乙個關鍵點。假如沒有修改操作的話,就像乙個簡單的樹形dp,方程如下 f i sigma sigma.觀察一下dp的過程,就是不斷地從前面的點走到後面的點,所以我們可以不...