樹鏈剖分 洛谷 P3384 模板 樹鏈剖分

2021-08-18 15:36:02 字數 2594 閱讀 5785

step1 problem:

題目

給你一棵n個點樹,m個操作,r是根,結果取模mod.

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

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

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

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

step2 involving algorithms:

樹鏈剖分

step3 ideas:

參考大牛部落格學習的

step4 code:

#includeusing namespace std;

#define lson root<<1

#define rson root<<1|1

#define mid int mid = (l+r)/2

const int n = 1e5+100;

vectormap[n];

int w[n], wt[n], n, root, mod;

//w[i] i點的初始權值,wt[i] 對映後的點 初始權值

int fq[n], dep[n], siz[n], son[n], idx[n], top[n], cnt;

//fq[i] 點i的父親,dep[i] 點i的深度,siz[i] 點i的兒子數(包括自己)

//son[i] 點i的重兒子, idx[i] 點i對映後的點,top[i] 該樹鏈的根

int a[n<<2], lazy[n<<2];//維護區間和,和lazy標記

void merge(int root)

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

mid;

build(lson, l, mid);

build(rson, mid+1, r);

merge(root);

}void pushdown(int root, int l, int r)

}void updata(int root, int l, int r, int ul, int ur, int v)

pushdown(root, l, r);

mid;

if(mid >= ul)

updata(lson, l, mid, ul, ur, v);

if(mid < ur) updata(rson, mid+1, r, ul, ur, v);

merge(root);

}int query(int root, int l, int r, int ul, int ur)

pushdown(root, l, r);

mid;

int res = 0;

if(mid >= ul)

res += query(lson, l, mid, ul, ur), res %= mod;

if(mid < ur) res += query(rson, mid+1, r, ul, ur), res %= mod;

return res;

}//以上都是線段樹區間更新的**,不會的話,請先學會。

void dfs1(int u, int f, int deep)//第一遍dfs,求fq,dep,siz,son

}}void dfs2(int u, int top)//第二遍dfs,求idx, top

}}void add(int u, int v)

void updata_path(int x, int y, int z)//更新x->y的路徑點權

//在同一條鏈上,直接更新就好了

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

updata(1, 1, n, idx[x], idx[y], z);

}int query_path(int x, int y)//求x->y路徑點權和,跟上面思路一樣

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

res += query(1, 1, n, idx[x], idx[y]), res %= mod;

return res;

}void updata_tree(int x, int z)//用到dfs序思想,子樹的結點編號是連續的

int query_tree(int x)

void init()

int main()

init();

dfs1(root, -1, 1);

dfs2(root, root);

build(1, 1, n);

int ok, x, y, z;

while(m--)

else if(ok == 2)

else if(ok == 3)

else

}return 0;

}

樹鏈剖分 洛谷P3384樹剖模板

如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根節點的子樹內所有節...

洛谷 P3384 模板 樹鏈剖分

如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根節點的子樹內所有節...

P3384 模板 樹鏈剖分 洛谷

題目鏈結 如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根節點的子...