樹鏈剖分基本步驟

2022-02-03 12:06:58 字數 1023 閱讀 7948

總體步驟:init();

dfs1(1);

dfs2(1,1);

build(1,1,n);

cl();

dfs1 處理出size[sj](子節點數),son[sj](重兒子),dep[sj](深度),vi[sj](點權,把邊權放在子節點上)。

dfs2 處理出top[sj](所在鏈的鏈首,輕兒子從子節點重新開始,重兒子從父節點繼承),id[sj](點出現的位置,用cnt標記),pos[sj](cnt位置的邊連著哪乙個點)。

id[x]=++cnt;

pos[cnt]=x;

if(son[x]) dfs2(son[x],y);

for(int i=h[x];i!=-1;i=b[i].ne)

if(b[i].v!=fa[x]&&b[i].v!=son[x]) dfs2(b[i].v,b[i].v);

build if(z==y) mx[x]=vi[pos[y]];

這個位置鏈的最大值等於這個位置的鏈所連點的權值。一般線段樹方法建樹。和線段樹有關的陣列要開四倍四倍四倍。。。

cl 分change和query

change 改變的邊編號要按輸入資料檢索,從線段樹上找到這條邊上作為子節點的點改變它的點權。

int now=(b1<<1)-1;

int fr=b[now].u,to=b[now].v;

if(fa[fr]==to) change(id[fr],b2,1,1,n);

else change(id[to],b2,1,1,n);

query query函式即為一般的線段樹查詢,把不在一條鏈上的兩個點向一條鏈上靠攏,時刻注意要求哪點在下層。如果本來就是點權,則id[x]不應該+1且id[x]==id[y]的情況是可行的。

int fx=top[x],fy=top[y],res=1<<31;

while(fx^fy)

{if(dep[fx]dep[y]) jh(x,y);

if(id[x]

因為我太弱了不寫就會很快忘掉qaq

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...

樹鏈剖分步驟

deep 記錄該節點的深度 siz 記錄以該節點為根的子樹的節點數 fa 記錄該節點的父親是誰 son 記錄該節點的重兒子是誰 top 記錄該節點所在的重鏈的根節點是誰 w 記錄該節點投影到數軸後的位置 即dfs序,線段樹要用 讀入,用空間池儲存邊 注意是雙向的 第一次dfs 記錄dep,siz,f...

演算法入門 樹鏈剖分 輕重鏈剖分

目錄 3.0 求 lca 4.0 利用資料結構維護資訊 5.0 例題 參考資料 資料結構入門 線段樹 發表於 2019 11 28 20 39 dfkuaid 摘要 線段樹的基本 建樹 區間查詢 單點修改 及高階操作 區間修改 單點查詢 區間修改 區間查詢 標記下傳 標記永久化 閱讀全文 樹鏈剖分用...