P2680 運輸計畫(二分 樹上差分)

2022-04-06 14:01:52 字數 1617 閱讀 9863

鏈結分析:

二分+樹上差分。

首先可以二分乙個答案,那麼所有比這個答案大的路徑,都需要減去些東西才可以滿足這個答案。

那麼減去的這條邊一定在所有的路徑的交集上。

那麼如果求快速的求出這個交集並判斷呢,樹剖可以,把所有大於的路徑都標記一下,然後判斷,複雜度太大了。

於是用到了樹上差分,get新技能。

在兩個端點出標記+1,在lca出標記-2,然後從葉子節點往上更新,對於一條邊是交集,那麼它標記的次數一定是大於這個答案的個數。然後判斷是否滿足即可。

各種優化:1、l,r的範圍,2、可以按dis排序,發現沒什麼用。

**

1

//luogu-judger-enable-o2

2 #include3 #include4 #include5 #include6 #include7 #include8

9using

namespace

std;

1011

const

int n = 300100;12

struct

edge

15 edge(int a,int b,int c)

16 }e[600100

];17

struct

que22

}q[n];

23int

head[n],tot;

24int deth[n],fa[n],num[n],dis[n],val[n],f[n][23

],tag[n];

25int

n,m,dfs_time;

2627 inline char

nc()

31 inline int

read()

37void add_edge(int u,int v,int

w) 41

void dfs(int u,int

fa) 52}

53void

init()

58int lca(int u,int

v) 69

bool check(int

x) 78}79

if (!cnt) return

true; //

如果沒有大於x的,直接返回true,加上這句快了不少。

80for (int i=n; i>=1; --i)

81 tag[f[num[i]][0]] +=tag[num[i]];

82for (int i=2; i<=n; ++i)

83if (val[i] >= limit && tag[i] == cnt) return

true;84

return

false;85

}86intmain ()

94 dfs(1,0

);95

init();

96for (int i=1; i<=m; ++i)

102//

sort(q+1,q+m+1);

103int ans =r;

104while ( l <=r )

109 cout <110return0;

111 }

P2680 運輸計畫 二分 樹上差分

又咕咕了幾天 qwq 我們先將原問題轉化為 log 2n 個判定問題 如何 ck x 把所有 x 的路徑在樹上標記 邊差分 然後找到被所有 x 路徑覆蓋的點 邊轉點,邊權下放點權 嘗試把這個點的權值改為零,檢查最長路徑的時間是否 leq x 若存在這樣的點,return true 否則 return...

P2680 運輸計畫 二分 LCA 樹上差分

公元20442044 年,人類進入了宇宙紀元。l 國有 nn 個星球,還有 n 1n 1 條雙向航道,每條航道建立在兩個星球之間,這 n 1n 1 條航道連通了 ll 國的所有星球。小 p 掌管一家物流公司,該公司有很多個運輸計畫,每個運輸計畫形如 有一艘物流飛船需要從 u iu i 號星球沿最快的...

洛谷P2680 運輸計畫(樹上差分 二分)

傳送門 考慮樹上亂搞 首先這是滿足二分性質的,如果在某個時間可以完成工作那麼比他更長的時間肯定也能完成工作 然後考慮二分,設當前答案為 mid 如果有一條鏈的長度大於 mid 那麼這條鏈上必須得刪去一條邊。我們可以貪心的刪去所有可以刪去的邊中最長的,然後看看最長邊減去刪去的邊是否小於等於 mid 如...