題目
樹剖裸題,這個題更可以深刻的理解樹剖中把樹上的節點轉換為區間的思想。
要注意在區間上連續的節點,一定是在一棵子樹中。
#include #define int long long
#define ls left, mid, root << 1
#define rs mid + 1, right, root << 1 | 1
#define n 600100
using namespace std;
int n, m, rot, mod, tot, cnt;
int data[n], id[n], dep[n], size[n], lin[n], ans[n * 8], lazy[n * 8], dp[n], fa[n], top[n], son[n];
struct edg e[n];
inline void add(int f, int t)
inline void pushup(int root)
inline void pushdown(int root, int left, int right)
}void build(int left, int right, int root)
int mid = (left + right) >> 1;
build(ls), build(rs);
pushup(root);
}
inline void update(int left, int right, int root, int add, int ql, int qr)
int mid = (left + right) >> 1;
pushdown(root, left, right);//線段樹的pushdown操作是為了彌補之前沒向下傳遞標記的坑。
if (ql <= mid)
update(ls, add, ql, qr);
if (qr > mid)
update(rs, add, ql, qr);
pushup(root);
} inline int query(int left, int right, int root, int ql, int qr)
void dfs1(int now, int f, int de)
}} void ulca(int x, int y, int z)
if (dep[x] > dep[y])
swap(x, y);
update(1, n, 1, z, id[x], id[y]);
}int qlca(int x, int y)
if (dep[x] > dep[y])
swap(x, y);
res = ( res + query(1, n, 1, id[x], id[y]) );
return res;
}void upd(int x, int y)
int que(int x)
void dfs2(int now, int t)
}signed main()
dfs1(rot, 0, 1);
dfs2(rot, rot);
build(1, n, 1);
for (int i = 1; i <= m; i++)
if (flag == 2)
if (flag == 3)
} return 0;}/*
5 5 2 24
7 3 7 8 0
1 21 5
3 14 1
3 4 2
3 2 2
4 51 5 1 3
2 1 3
*/
洛谷P3178 HAOI2015 樹上操作
有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數和運算元。...
洛谷 P3178 HAOI2015 樹上操作
這篇題解原發於我的blog 這是一道樹鏈剖分的板子題,純粹的模板題事實上模板題比他難 事實上只要做過這道題p3384 模板 樹鏈剖分就可以我把題目難度提公升了 畢竟我是剛切完板子題的人,初生牛犢不怕虎,直接再打一遍練練手被逼的 記住因為這題沒有提供取模的數,因為 10 6 times10 5 2 1...
洛谷 P3178 HAOI2015 樹上操作
有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數和運算元。...