長鏈剖分學習筆記

2022-05-25 10:48:11 字數 3029 閱讀 7287

長鏈剖分在去年noip之前就想學了,被我鴿到了現在(。

省選竟然考了啊喂(哭死 雖然那個時候三個月沒寫**的狀態即使我會寫也沒救

都是小問題

長鏈剖分 看名字就知道是類似樹鏈剖分的一類東西

樹鏈剖分其實是重鏈剖分 但是是市面上流傳最廣的樹鏈剖分 好像大家都習慣直接稱之為樹鏈剖分...

重鏈剖分是按照子樹重量進行剖分 長鏈剖分就是按照子樹(最長鏈)長度進行剖分

它的優勢在於維護只與樹的深度有關的資訊時每條重鏈只在頂端合併一次 因此對應上優秀的實現就是線性的複雜度

優秀的實現其實也很簡單

我們第二遍dfs的時候按照先遞迴重鏈並編號,這樣的話記憶體是連續的可以直接繼承重兒子,且恰好比重兒子多乙個位置,對應整條鏈的長度。

板子:cf1009f

本來就是educationalround 估計就是給大家科普這個吧?

//

love and freedom.

#include#include

#include

#include

#define ll long long

#define inf 20021225

#define n 1000100

using

namespace

std;

intread()

while(ch>='

0'&&ch<='

9') s=s*10+ch-'

0',ch=getchar();

return f*s;

}struct edgee[n<<1

];int

in[n],cnt,f[n],len[n],id[n],tms,son[n],ans[n];

void add(int x,int

y)void dfs(int x,int

fr)}

void calc(int x,int

fr) }

if(f[id[x]+ans[x]]==1) ans[x]=0;}

intmain()

dfs(

1,0); calc(1,0

);

for(int i=1;i<=n;i++) printf("

%d\n

",ans[i]);

return0;

}

view code

bzoj3252

好像跟長鏈剖分沒毛關係...就是個簡單貪心...

類似長鏈剖分一樣剖出長鏈來,但是邊權代替長度,然後直接取前k項就好了。

//

love and freedom.

#include#include

#include

#include

#include

#define ll long long

#define inf 20021225

#define n 200010

using

namespace

std;

intread()

while(ch>='

0'&&ch<='

9') s=s*10+ch-'

0',ch=getchar();

return f*s;

}struct edgee[n<<1

];int

in[n],cnt,len[n],id[n],tms,son[n],a[n];

priority_queue

hp; ll f[n];

void add(int x,int

y)void dfs(int x,int

fr) f[x]+=a[x];

}void dfs2(int x,int t,int

fr)}

intmain()

view code

想補希望,但它好像沒有什麼希望...

(咕咕咕)

cogs2652 秘術「天文密葬法」

0/1分數規劃+長鏈剖分就好啦

對於每個位置再額外記錄乙個tag就能o(1)繼承啦

(發現了新oj!河南省實驗中學tql!)

//

love and freedom.

#include#include

#include

#include

#define ll long long

#define inf 20021225

#define eps 1e-4

#define n 200010

#define db double

using

namespace

std;

intread()

while(ch>='

0'&&ch<='

9') s=s*10+ch-'

0',ch=getchar();

return f*s;

}struct edgee[n<<1

];int

in[n],cnt,tot,m,n;

void add(int x,int

y)int

id[n],len[n],son[n],fa[n],dia;

db f[n],a[n],b[n],tag[n];

void dfs(int x,int

fr)}

db ans;

void calc(int x,int

fr,db mid)

if(m<=len[x]) ans=min(ans,f[id[x]+m-1]+tag[x]);

}db erf()

returnl;}

intmain()

dfs(

1,0);//

printf("%d\n",dia);

if(dia"-1"

);

else printf("

%.2lf\n

",erf());

return0;

}

view code

學習筆記 長鏈剖分

處理和深度有關的一些事情 長鏈剖分的 和重鏈剖分一樣。只是重兒子條件不同罷了。之前和沒學一樣。補充 本質是優化dp,dp一維和深度有關 實現有一些類似dsu on tree 長鏈剖分還有乙個操作精髓是繼承長兒子的資訊 通常用指標分配記憶體,使得長兒子資訊更新位置恰好是x的位置偏移一位 共用部分陣列,...

長鏈剖分學習筆記

學這個之前應該要比較熟悉重鏈剖分,推薦一下這篇部落格。我們模擬重鏈剖分,定義每個點所有兒子中,子樹深度最大的點為它的重兒子,那麼整棵樹就被劃分成了一些不相交的重鏈,然後首先就有乙個性質那就是所有重鏈長度和是 o n 級別的,這個東西很顯然,還有乙個性質就是乙個點的k級祖先所在重鏈長度一定大於等於k,...

長鏈剖分學習筆記

長鏈剖分,也屬於樹鏈剖分的一種方式,但是其與經典的重鏈剖分又不太一樣。在重鏈剖分中,我們評判兒子重或輕的方式是比較其子樹節點數量。在長鏈剖分中,我們以子樹中最深的葉節點深度的大小來比較。其他步驟與重鏈剖分類似,都是兩遍dfs即可解決,都是o n 的複雜度。接下來,我們來看兩個長鏈剖分的經典問題.時間...