2018 08 27 模板 樹鏈剖分換根(模板)

2021-08-26 03:02:36 字數 1770 閱讀 8946

描述

給定一棵大小為 n 的有根點權樹,支援以下操作:

• 換根

• 修改點權

• 查詢子樹最小值

輸入第一行兩個整數 n, q ,分別表示樹的大小和運算元。

接下來n行,每行兩個整數f,v,第i+1行的兩個數表示點i的父親和點i的權。保證f < i。如 果f = 0,那麼i為根。輸入資料保證只有i = 1時,f = 0。

接下來 m 行,為以下格式中的一種:

• v x y表示把點x的權改為y

• e x 表示把有根樹的根改為點 x

• q x 表示查詢點 x 的子樹最小值

輸出對於每個 q ,輸出子樹最小值。

樣例輸入

3 7

0 1

1 2

1 3

q 1

v 1 6

q 1

v 2 5

q 1

v 3 4

q 1樣例輸出

1 2 3 4

提示對於 100% 的資料:n, q ≤ 10^5。

標籤leo

**訓練ing。。。

先做了一道換根樹剖的板子,調了很久發現lca寫錯了也是很感動。。。

**:

#include

#define lc (p<<1)

#define rc (p<<1|1)

#define mid (t[p].l+t[p].r>>1)

#define n 100005

using

namespace

std;

inline

int read()

inline

void write(int x)

int n,q,fa[n],first[n],top[n],dep[n],hson[n],siz[n],num[n],pred[n],a[n],rt,cnt=0,tot=0;

struct edgee[n<<1];

struct nodet[n<<2];

inline

void dfs1(int p)

}inline

void dfs2(int p,int tp)

}inline

int min(int a,int b)

inline

void build(int p,int l,int r)

build(lc,l,mid),build(rc,mid+1,r),pushup(p);

}inline

void update(int p,int k,int v)

if(k<=mid)update(lc,k,v);

else update(rc,k,v);

pushup(p);

}inline

int query(int p,int ql,int qr)

inline

int lca(int x,int y)

if(dep[x]return hson[y];

}inline

void add(int u,int v)

int main()

dfs1(1),dfs2(1,1),build(1,1,n);

while(q--)

}puts("");

}else

if(s[0]=='e')rt=read();

else

}exit(0);

return

0;}

樹鏈剖分 樹剖換根

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

樹鏈剖分換根

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

樹鏈剖分 模板

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...