inline 神奇的東西
最好戒掉吧(read()除外)
這道題將求解性問題轉化為判定性問題,當然就是二分答案了
二分刪掉邊後最短路徑的最大值 mid
將所有的比mid大的詢問求交集:樹上差分,cnt[s] ++, cnt[t] ++, cnt[lca(s, t)] -= 2
最後統計每個節點以及該節點的子樹的cnt的和,若
和==比mid大的詢問數量,則說明該點與其父親組成
的這條邊在所有邊的交集上
判斷 :最大路徑-最大的交集中的邊
#include usingnamespace
std;
const
int n = 3e5 + 10
;#define gc getchar()
intcnt[n], tree[n], fa[n], siz[n], son[n], topp[n], deep[n], head[n];
int n, m, now = 1
, tim;
intl[n], r[n], d[n], dis[n];
intlca[n];
struct node g[n << 1
];int
js;
inline
intread()
void add(int u, int v, int
w)void dfs_find_son(int u, int f_, int
dep)
} }void dfs_to_un(int u, int
tp)}
int lca(int x, int
y)
return deep[x] > deep[y] ?y : x;
}void calc(int
u) }
}bool see(int
x)int
main()
dfs_find_son(
1, 0, 1
); dfs_to_un(
1, 1
);
for(int i = 1; i <= m; i ++)
while(l <=r)
printf("%d
", ans);
return0;
}/*6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5*/
luogu2680 運輸計畫
很明顯,由於是求最長路的最小值,我們可以使用二分求解.我們二分乙個長度 mid 將所有使得 dis u,v 大於 mid 的點對 u,v 找出,設總共有 m 條這樣的邊,那麼我們需要改變的改變邊一定是被這 m 條邊都經過的邊,所以我們只需要找到滿足這個要求的長度最大的改變邊使得這 m 條邊中最長的一...
Luogu2680 運輸計畫
我們對每條邊 i 單獨考慮,那麼設 v i 為這條邊的長度,經過它的路徑長度集合為 s 未經過它的路徑長度集合為 t ans i max begin s v i t end ans min ans i 對於 s 我們直接對於一條長度為 l 的路徑,該路徑上的邊都對 l 取 max 用樹鏈剖分很容易處...
luogu2680 運輸計畫
首先二分列舉答案t,考慮刪去的邊應滿足的條件 所有大於 t的鏈全部經過且長度不小於最長鏈 t,第二個條件很好判斷,考慮第乙個條件。先考慮有祖先 後代關係的鏈,用如果把這條鏈到 1看成乙個序列,那麼差分一下再 dfs一遍就可以對這條鏈上每乙個點打上標記。然後沒有祖先 後代關係的鏈,同樣可以分解成兩條鏈...