模板 重鏈剖分

2022-05-07 21:42:14 字數 1888 閱讀 2374

如題,已知一棵包含n個結點的樹(連通且無環),每個節點上包含乙個數值,需要支援以下操作:

操作1: 格式: 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z

操作2: 格式: 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和

操作3: 格式: 3 x z 表示將以x為根節點的子樹內所有節點值都加上z

操作4: 格式: 4 x 表示求以x為根節點的子樹內所有節點值之和

小心不要抄錯。這個常數比較小。

#include#define lc (o<<1)

#define rc (o<<1|1)

typedef long long ll;

using namespace std;

const int maxn = 100000 + 5;

int dep[maxn], siz[maxn], son[maxn], fa[maxn], top[maxn], tid[maxn], rnk[maxn], cnt;

int n, m, r, mod;

int a[maxn];

int head[maxn], etop;

struct edge e[maxn * 2];

inline void init(int n)

inline void addedge(int u, int v)

struct segmenttree

void pushdown(int o, int l, int r)

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

lz[o] = 0;

}void update(int o, int l, int r, int ql, int qr, int v) else

}int query(int o, int l, int r, int ql, int qr) else

}} st;

void init1()

void dfs1(int u, int t)

}void init2()

void dfs2(int u, int t)

}int query1(int u, int v) else

}if(tid[u] <= tid[v])

ret += st.query(1, 1, n, tid[u], tid[v]);

else

ret += st.query(1, 1, n, tid[v], tid[u]);

return ret % mod;

}inline int query2(int u)

inline void update1(int u, int v, int val) else

}if(tid[u] <= tid[v])

st.update(1, 1, n, tid[u], tid[v], val);

else

st.update(1, 1, n, tid[v], tid[u], val);

}inline void update2(int u, int val)

void op1()

void op2()

void op3()

void op4()

int main()

init(n);

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

init1();

dfs1(r, -1);

init2();

dfs2(r, r);

st.build(1, 1, n);

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

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

樹鏈剖分模板

點權模板 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...