樹鏈剖分模板

2021-08-07 10:47:04 字數 3168 閱讀 7399

點權模板:

1、m a b c將節點a到節點b路徑上所有點都染成顏色c;

2、q a b詢問節點a到節點b路徑上的顏色段數量(連續相同顏色被認為是同一段),如「112221」由3段組成:「11」、「222」和「1」。

const int n = 100100;

struct edge

g[n*2];

int cnt, head[n];

int dep[n], siz[n], son[n], fat[n], id[n], top[n];

int color[n], d[n][2], pos[n];

int n, m, num;

struct node

tr[n*4];

void init()

void add_edge(int v, int u)

void dfs1(int v, int fa, int d)

}}void dfs2(int v, int tp)

}void push_up(int k)

void push_down(int k)

}void build(int l, int r, int k)

int mid = (l + r) >> 1;

build(l, mid, k << 1);

build(mid + 1, r, k << 1|1);

push_up(k);

}void update(int l, int r, int c, int k)

push_down(k);

int mid = (tr[k].l + tr[k].r) >> 1;

if(l <= mid) update(l, r, c, k << 1);

if(r > mid) update(l, r, c, k << 1|1);

push_up(k);

}int query(int l, int r, int k)

}int query_node(int

x, int k)

void update(int v, int u, int c)

//和邊權不同的地方

if(dep[v] > dep[u]) swap(v, u);

update(id[v], id[u], c, 1);

}int query(int v, int u)

//和邊權不同的地方

if(dep[v] > dep[u]) swap(v, u);

return ans += query(id[v], id[u], 1);

}int main()

dfs1(1, 0, 1);

dfs2(1, 1);

for(int i = 1; i <= n; i++) pos[id[i]] = color[i];

build(1, num, 1);

char ch;

int a, b, c;

while(m--)

else}}

return

0;}

邊權模板:
const int n = 100100;

struct edge

g[n*2];

int cnt, head[n];

int dep[n], siz[n], son[n], fat[n], id[n], top[n];

int d[n][3], pos[n];

int n, m, num;

struct node

tr[n*4];

void add_edge(int v, int u)

void dfs1(int v, int fa, int d)

}}void dfs2(int v, int tp)

}void push_up(int k)

void push_down(int k)

}void build(int l, int r, int k)

int mid = (l + r) >> 1;

build(l, mid, k << 1);

build(mid + 1, r, k << 1|1);

push_up(k);

}void update(int l, int r, int c, int k)

push_down(k);

int mid = (tr[k].l + tr[k].r) >> 1;

if(l <= mid) update(l, r, c, k << 1);

if(r > mid) update(l, r, c, k << 1|1);

push_up(k);

}int query(int l, int r, int k)

int query_node(int

x, int k)

void update(int v, int u, int c)

if(v == u) return;

if(dep[v] > dep[u]) swap(v, u);

update(id[son[v]], id[u], c, 1);

}int query(int v, int u)

if(v == u)

/*此處特別判斷,比如u是根節點,v到根節點路徑是一段連續的重鏈*/

if(dep[v] > dep[u]) swap(v, u), swap(cv, cu);

ans += query(id[son[v]], id[u], 1);

//最後查詢的這條鏈和兩條鏈相接,所以都要判斷相接處顏色是否相同

x = query_node(id[u], 1);

if(x == cu) ans--;

x = query_node(id[son[v]], 1);

if(x == cv) ans--;

return ans;

} int main()

dfs1(1, 0, 1);

dfs2(1, 1);

for(int i = 1; i <= n - 1; i++)

build(1, num, 1);

for(int i = 1; i <= m; i++)

else}}

return

0;}

樹鏈剖分 模板

class match node a n struct no no aa n 4 void init void addpage int x,int y void dfs int s,int faa,int h 根節點,父節點和深度的 if max 0 son s sign void dfs2 int...

模板 樹鏈剖分

define maxn 50010 define l u u 1 define r u u 1 1 寫在類裡面爆棧 int n,m,q int tim 時間戳 int num maxn 樹上每個節點的初始值 int siz maxn siz u 表示以u為根的子樹的節點數 int top maxn ...

模板 樹鏈剖分

如果你會了樹上dp,還會線段樹 沒錯!我都會啊!那你為什麼寫不出樹鏈剖分?by勇者和路由器的對話,今天二位仍然過得十分愉快 bzoj1036 zjoi2008 樹的統計 題目描述 一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.cha...