處理和深度有關的一些事情
長鏈剖分的**和重鏈剖分一樣。只是重兒子條件不同罷了。
之前和沒學一樣。。。
補充:本質是優化dp,dp一維和深度有關
實現有一些類似dsu on tree
長鏈剖分還有乙個操作精髓是繼承長兒子的資訊
通常用指標分配記憶體,使得長兒子資訊更新位置恰好是x的位置偏移一位
共用部分陣列,相對獨立又相互依存,這點和dsu on tree有不同
用到的長鏈剖分性質:最長
使得:1.利於分配記憶體
2.當前x的最大深度從長兒子繼承過來,所以陣列一定是最深的。減少討論
3.k級祖先所在鏈長大於等於k
利用k級祖先的鏈一定長度大於等於k的條件。配合預處理倍增陣列、鏈頂記錄資訊、二進位制拆分出最高位。實現o(1)查詢
因為長鏈之和是n,所以對每個長鏈處理的複雜度都是正確的。
模板題。最大值位置在更新時候進行偏移即可。
**:
#include#define reg register intview code#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
using
namespace
std;
typedef
long
long
ll;template
il void rd(t &x)
template
il void output(t x)
template
il void ot(t x)
template
il void prt(t a,int st,int nd)
namespace
miraclee[
2*n];
inthd[n],cnt;
int *f[n],memchi[n],ans[n],*cur=memchi;
void add(int x,int
y)void dfs(int x,int
fa) len[x]=len[son[x]]+1;}
void dp(int x,int
fa) }
if(f[x][0]==f[x][ans[x]]) ans[x]=0;}
intmain()
dfs(
1,0);
f[1]=cur;cur+=len[1
]; dp(
1,0);
for(reg i=1;i<=n;++i)
return0;
}}signed main()
/*author: *miracle*
date: 2019/3/17 15:44:31
*/
0/1分數規劃,二分答案,記錄深度為j的點權和最小值,m是固定的,直接更新答案
平移陣列,整體加上ci,用tag[x]維護整體加
主要還是dp式子吧,,,
bzoj3522: [poi2014]hotel
n<=1e6個點,邊權為1,求樹上不超過l的鏈的條數
f[x][j],長度小於等於j的點的個數
可以利於我們列舉y的一邊,直接貢獻答案。
合併有點苟,因為是乙個字首和,所以不斷更新tag[x],len[x]>len[y]的超過的部分,都加上f[y][len[y]-1]。
**:
//view codeluogu-judger-enable-o2
#include#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
using
namespace
std;
typedef
long
long
ll;template
il void rd(t &x)
template
il void output(t x)
template
il void ot(t x)
template
il void prt(t a,int st,int nd)
namespace
miraclee[
2*n];
inthd[n],cnt;
void add(int x,int
y)int *f[n],memchi[n],*cur=memchi;
intlen[n],son[n];
inttag[n];
void dfs(int x,int
fa) len[x]=len[son[x]]+1;}
ll ans;
void dp(int x,int
fa) ll tmp=f[y][len[y]-1]+tag[y];
for(reg j=1;j<=len[y];++j)
f[x][
0]-=tmp;
tag[x]+=tmp;
}//cout<
for(reg i=0;i//
cout/
}cout/
cout<
intmain()
dfs(
1,0);
//prt(len,1,n);
//prt(son,1,n);
f[1]=cur;cur+=len[1
]; dp(
1,0);
printf(
"%lld
",ans);
return0;
}}signed main()
/*author: *miracle*
date: 2019/3/17 18:10:50
*/
長鏈剖分思想是基於和深度有關的dp
dsu on tree思想是莫隊,全域性資料結構維護,暴力新增子樹刪除子樹
dsu on tree由於可以全域性維護並且子樹暴力查詢,可以做的事情是長鏈剖分的超集
但是長鏈剖分在特殊情況下的o(n)是無法超越的
長鏈剖分學習筆記
學這個之前應該要比較熟悉重鏈剖分,推薦一下這篇部落格。我們模擬重鏈剖分,定義每個點所有兒子中,子樹深度最大的點為它的重兒子,那麼整棵樹就被劃分成了一些不相交的重鏈,然後首先就有乙個性質那就是所有重鏈長度和是 o n 級別的,這個東西很顯然,還有乙個性質就是乙個點的k級祖先所在重鏈長度一定大於等於k,...
長鏈剖分學習筆記
長鏈剖分,也屬於樹鏈剖分的一種方式,但是其與經典的重鏈剖分又不太一樣。在重鏈剖分中,我們評判兒子重或輕的方式是比較其子樹節點數量。在長鏈剖分中,我們以子樹中最深的葉節點深度的大小來比較。其他步驟與重鏈剖分類似,都是兩遍dfs即可解決,都是o n 的複雜度。接下來,我們來看兩個長鏈剖分的經典問題.時間...
長鏈剖分學習筆記
終於認真寫一次標題了 因為一些不明原因,之前對 dsu on tree 的理解沒有完全寫出來,在這裡會一起寫,因為兩者極為相似。先來看一下 dsu on tree 和長鏈剖分的對比。dsu on tree 實際上就是重鏈剖分,可以處理很多與子樹有關且不帶修改的題目 離線 複雜度 mathcal nl...