樹鏈剖分步驟

2021-07-17 04:59:53 字數 2145 閱讀 6456

deep:記錄該節點的深度

siz:記錄以該節點為根的子樹的節點數

fa:記錄該節點的父親是誰

son:記錄該節點的重兒子是誰

top:記錄該節點所在的重鏈的根節點是誰

w:記錄該節點投影到數軸後的位置(即dfs序,線段樹要用)

讀入,用空間池儲存邊(注意是雙向的);

第一次dfs:

記錄dep,siz,fa,son(找siz最大的兒子做重兒子)

第二次dfs:

記錄w;

順著son處理重鏈記錄top(包括自己)

之後處理輕鏈

【偽**】

設現處理x節點,其重父親為tp

dfs2(x,tp)

time++;

w[x]=time;

top[x]=tp;

if(有重兒子)

建線段樹

修改:從x到y的節點加d

while(top[x]!=top[y])

if(dep[x] > dep[y]) swap(x,y);

insert(1,1,n,w[x],w[y],d);

6.查詢(和線段樹一樣就不說了)

貼個**吧,hdu3966,比較經典的樹剖題

#include 

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define zero(a) memset(a,0,sizeof(a))

#define minus(a) memset(a,-1,sizeof(a))

const

int max_n = 50100;

struct edgee[max_n * 3];

int siz[max_n];

int dep[max_n];

int fa[max_n];

int son[max_n];

int top[max_n];

int w[max_n];

int a[max_n];

int h[max_n];

int n,m,q,ep,time;

int cnt[max_n * 4];

inline

void add(int x,int y)

void dfs1(int x,int fat,int deep)

return;

}void dfs2(int x,int tp)

}return;

}void insert(int rt,int l,int r,int a,int b,int val)

int lson = rt*2;

int rson = rt*2+1;

int mid = (l+r)/2;

insert(lson,l,mid,a,b,val);

insert(rson,mid+1,r,a,b,val);

return;

}inline

void revise(int x,int y,int d)

if(dep[x] > dep[y]) swap(x,y);

insert(1,1,n,w[x],w[y],d);

return;

}int query(int rt,int l,int r,int idx,int sum)

inline

void ask(int x)

inline

void init()

inline

void read()

return;

}inline

void build()

inline

void solve()

scanf("%d %d %d",&x,&y,&d);

if(c[0]=='d')

d=-d;

revise(x,y,d);

}return;

}int main()

return

0;}

樹鏈剖分基本步驟

總體步驟 init dfs1 1 dfs2 1,1 build 1,1,n cl dfs1 處理出size sj 子節點數 son sj 重兒子 dep sj 深度 vi sj 點權,把邊權放在子節點上 dfs2 處理出top sj 所在鏈的鏈首,輕兒子從子節點重新開始,重兒子從父節點繼承 id s...

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 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...

樹鏈剖分 樹剖換根

這是一道模板題。給定一棵 n 個節點的樹,初始時該樹的根為 1 號節點,每個節點有乙個給定的權值。下面依次進行 m 個操作,操作分為如下五種型別 換根 將乙個指定的節點設定為樹的新根。修改路徑權值 給定兩個節點,將這兩個節點間路徑上的所有節點權值 含這兩個節點 增加乙個給定的值。修改子樹權值 給定乙...