樹上操作 樹鏈剖分 線段樹

2021-09-26 16:36:34 字數 1895 閱讀 8741

有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個

操作,分為三種:

操作 1 :把某個節點 x 的點權增加 a 。

操作 2 :把某個節點 x 為根的子樹中所有點的點權都增加 a 。

操作 3 :詢問某個節點 x 到根的路徑中所有點的點權和。

樹鏈剖分後,節點x及其子樹節點會在一段連續的區間內,用線段樹維護區間和就可以了。注意如果是求根節點到根節點的,及1--1的,那麼直接輸出根節點的值就可以了,dfs2也要注意,當s==e的時候,tmp要加上根節點的值。

#include #include #include #include #include using namespace std;

typedef long long ll;

const int n = 1e5+5;

int n, m, cnt, tot;

int fa[n], dep[n], size[n], son[n], top[n], in[n], out[n], num[n], head[2*n];

ll value[n];

struct edge edge[2*n];

struct node tr[n<<2];

void add(int a, int b)

void dfs1(int d, int f, int u) // d:深度,f:父節點,u:當前節點

}void dfs2(int u, int tp) // u:當前節點,tp:鏈的頂端節點

out[u] = tot;

}void pushup(int m)

void pushdown(int m)

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

int mid = (l + r) >> 1;

build(m<<1, l, mid);

build(m<<1|1, mid + 1, r);

pushup(m);

}void change(int m, int id, ll val)

pushdown(m);

int mid = (tr[m].l + tr[m].r) >> 1;

if(id <= mid) change(m<<1, id, val);

else change(m<<1|1, id, val);

pushup(m);

}void updata(int m, int l, int r, ll val)

pushdown(m);

int mid = (tr[m].l + tr[m].r) >> 1;

if(l <= mid) updata(m<<1, l, r, val);

if(r > mid) updata(m<<1|1, l, r, val);

pushup(m);

}ll ask(int m, int l, int r)

ll find(int s, int e)

tmp += ask(1, in[fs], in[s]);

s = fa[fs];

fs = top[s];

} if(s == e) return tmp + ask(1, in[s], in[s]); // 當s==e時,說明現在s在根節點,要加上根節點的值

if(dep[s] > dep[e]) swap(s, e);

return tmp + ask(1, in[s], in[e]);

}int main()

dfs1(1, 0, 1);

dfs2(1, 1);

build(1, 1, n);

while(m--)

else if(op == 2)

else

}return 0;

}

LCA 樹鏈剖分 線段樹

給出乙個 n 個節點的有根樹 編號為 0 到 n 1 根節點為 0 乙個點的深度定義為這個節點到根的距離 1 設 dep i 表示點 i 的深度,lca i,j 表示 i 與 j 的最近公共祖先。有 q 次詢問,每次詢問給出 l,r,z 求 dep lca i,z 即,求在 l,r 區間內的每個節點...

HAOI2015 樹上操作 樹鏈剖分

1963.haoi2015 樹上操作 有一棵點數為n的樹,以點1為根,且樹點有權值。然後有m個操作,分為三種 操作1 把某個節點x的點權增加a。操作2 把某個節點x為根的子樹中所有點的點權都增加a。操作3 詢問某個節點x到根的路徑中所有點的點權和。第一行兩個整數n,m,表示點數和運算元。接下來一行n...

HAOI2015 樹上操作 樹鏈剖分

有一棵點數為n的樹,以點1為根,且樹點有權值。然後有m個操作,分為三種 操作1 把某個節點x的點權增加a。操作2 把某個節點x為根的子樹中所有點的點權都增加a。操作3 詢問某個節點x到根的路徑中所有點的點權和。第一行兩個整數n,m,表示點數和運算元。接下來一行n個整數,表示樹中節點的初始權值。接下來...