傳送門
邊分治比點分治好的一點就是每次分出來都只有2個集合
如果遇到難以合併的資訊的時候邊分治就很有用了
手動轉二叉樹
每次可以按照權值大小排序後對兩個集合雙指標掃兩遍
具體實現可以看**
複雜度o(n
log2
n)
o(nlog^2n)
o(nlog
2n)
#include
using
namespace std;
const
int rlen=
1<<20|
1;#define ll long long
#define pb push_back
#define pii pair
#define gc getchar
inline
intread()
const
int n=
200005
;const
int inf=
1e9;
int n,pn,mx,mxsiz,tot,rt;
ll ans;
int adj[n]
,nxt[n<<1]
,to[n<<1]
,siz[n]
,val[n<<1]
,vis[n<<1]
,cnt=
1,pt[2]
,a[n]
;pii tmp[2]
[n];
#define fi first
#define se second
inline
bool
comp
(const pii &a,
const pii &b)
vector<
int> son[n]
;inline
void
addedge
(int u,
int v,
int w)
void
dfs(
int u,
int f)
}inline
void
rebuild()
}else}}
}inline
void
getrt
(int u,
int f)
}void
getdis
(int kd,
int u,
int f,
int dep,
int va)
}void
solve
(int u,
int sz)
for(
int i=
1,j=
1,mxl=
0;i<=pt[1]
;i++
)int ksz=siz[to[now]];
solve
(to[now]
,ksz)
,solve
(to[now^1]
,sz-ksz);}
intmain()
dfs(1,
0),rebuild()
,solve(1
,n);
cout<}
BZOJ2870 最長道路
許可權題 給出一棵樹,點有點權,找到樹上的一條路徑使得路徑上點的個數和其中點權最小的點的點權之積最大,輸出最大值。邊分治板子題啦。邊分治後對於分出來的兩棵子樹 按到左右根的最小點權排序後直接用單調指針對每乙個點找到另一棵樹中的最優點即可。code include using namespace st...
bzoj 2870 最長道路tree
題目 邊分治邊分和點分相比就是找到一條重心邊,考慮所有經過這條邊的路徑,之後斷開這條邊分成兩個聯通塊,繼續分治 由於每次分治重心是一條邊,所以只會產生兩個聯通塊,考慮兩個聯通塊顯然要比像點分那樣考慮多個聯通塊容易 但是邊分有乙個問題,就是遇到菊花圖就自閉了,複雜度變成了 o n 2 我們注意到邊分的...
BZOJ2870 最長道路tree
題解 子樹分治的做法可以戳這裡 可是碼量。這裡介紹另一種好寫又快的方法。我們還是一顆一顆子樹處理,處理完乙個子樹,考慮列舉最小值。如果我們現在處理到了x節點,它到根的min為w。那麼我們就可以在以前的資訊中找出min w且長度最長的一條鏈並且用它和該鏈合併,同時更新答案。這個顯然可以用樹狀陣列搞。處...