BZOJ 3306 樹 樹鏈剖分

2021-07-09 22:31:00 字數 1882 閱讀 1971

和bzoj 3083比就是弱化版了。

樣例都有點像?

#include 

#include

using

namespace

std;

const

int n = 100005, m = n * 3, inf = 0x7fffffff;

int read()

int next[m], to[m], head[n], sz[n], son[n], top[n], c[n], f[n], fa[n], dep[n], pos[n], cnt = 0;

int end[n], num[m], lazy[m], rt = 1, n, tot = 0;

void add(int u, int v)

void dfs1(int x)

} void dfs2(int x, int t)

void pushdown(int t)

}void modify(int t, int l, int r, int ql, int qr, int z)

pushdown(t);

if (qr <= mid) modify(t * 2, l, mid, ql, qr, z);

else

if (mid < ql) modify(t * 2 + 1, mid + 1, r, ql, qr, z);

else modify(t * 2, l, mid, ql, mid, z), modify(t * 2 + 1, mid + 1, r, mid + 1, qr, z);

num[t] = min(num[t * 2], num[t * 2 + 1]);

}void modify(int x, int y, int z)

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

modify(1, 1, n, pos[x], pos[y], z);

}int query(int t, int l, int r, int ql, int qr)

int query(int x)

return ans;

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

build(t * 2, l, mid); build(t * 2 + 1, mid + 1, r);

num[t] = min(num[t * 2], num[t * 2 + 1]);

}int main()

}return

0;}

time limit: 10 sec memory limit: 256 mb

submit: 608 solved: 192

給定一棵大小為 n 的有根點權樹,支援以下操作:

* 換根

* 修改點權

* 查詢子樹最小值

第一行兩個整數 n, q ,分別表示樹的大小和運算元。

接下來n行,每行兩個整數f,v,第i+1行的兩個數表示點i的父親和點i的權。保證f < i。如 果f = 0,那麼i為根。輸入資料保證只有i = 1時,f = 0。

接下來 m 行,為以下格式中的一種:

• v x y表示把點x的權改為y

• e x 表示把有根樹的根改為點 x

• q x 表示查詢點 x 的子樹最小值

對於每個 q ,輸出子樹最小值。

3 7

0 1

1 2

1 3

q 1

v 1 6

q 1

v 2 5

q 1

v 3 4

q 11

2 3

4對於 100% 的資料:n, q ≤ 10^5。

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...

樹鏈剖分 bzoj2243

time limit 20 sec memory limit 512 mb submit 2492 solved 960 submit status 給定一棵有n個節點的無根樹和m個操作,操作有2類 1 將節點a到節點b路徑上所有點都染成顏色c 2 詢問節點a到節點b路徑上的顏色段數量 連續相同顏色...

bzoj4034 樹鏈剖分

time limit 10 sec memory limit 256 mb submit 7576 solved 2597 submit status discuss 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個 操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作...