洛谷p3384 【模板】樹鏈剖分錯誤記錄
首先感謝\(lfd\)在課上調了出來\(orz\)
\(1\).以後少寫全域性變數
\(2\).線段樹遞迴的時候最好把左右區間一起傳
\(3\).寫\(dfs\)的時候不要寫錯名字
\(4\).使用線段樹的操作的時候才要用到\(dfs\)序
\(5\).需要開乙個陣列來記錄在\(dfs\)序下的節點是什麼也方便線段樹的賦值
\(6\).注意\(down\)函式內怎樣更新
\(7\).在查詢的時候並不需要向上更新
由於\(yxj\)看了\(lfd\)敲的樹鏈剖分感覺壓完行之後非常的好看,由此\(yxj\)也踏上了瘋狂壓行的不歸路
code:
#include #include #include #include #define lson k << 1
#define rson k << 1 | 1
using namespace std;
const int n = 1e5+7;
int n, m, r, p, dfn[n], top[n], son[n], dep[n], fa[n], siz[n], tot, head[n << 1], cnt, num, x, y, z, w[n], l, r, ans, pre[n];
struct node tr[n << 2];
struct node e[n << 1];
int read()
while(isdigit(ch))
return s * w;
}void build(int k, int l, int r)
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
tr[k].w = (tr[lson].w + tr[rson].w) % p;
}void add(int x, int y)
void dfs(int x)
} void dfs1(int x)
void down(int k)
void change_query(int k)
if(tr[k].f) down(k);
int mid = (tr[k].l + tr[k].r) >> 1;
if(l <= mid) change_query(lson);
if(r > mid) change_query(rson);
tr[k].w = (tr[lson].w + tr[rson].w) % p;
}void work(int x, int y)
if(dep[x] > dep[y]) swap(x, y);
l = dfn[x], r = dfn[y]; change_query(1);
}void ask_query(int k)
if(tr[k].f) down(k);
int mid = (tr[k].l + tr[k].r) >> 1;
if(l <= mid) ask_query(lson);
if(r > mid) ask_query(rson);
tr[k].w = (tr[lson].w + tr[rson].w) % p;
}void work1(int x, int y)
if(dep[x] > dep[y]) swap(x, y);
l = dfn[x]; r = dfn[y]; ask_query(1);
}int main()
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 模板 樹鏈剖分
樹鏈剖分詳情 跳轉大佬部落格 解題心得 個人看來其實樹鏈剖分就是把一棵標號沒有實際意義的樹重新標號,標號的規則按照重鏈優先,在有序之後用線段樹之類的資料結構來維護。include using namespace std const int maxn 1e5 100 struct node node ...