作為乙個比樹剖板子還板子的題目,它竟讓我卡了近乙個下午。。。。出去不敢說自己是學過樹剖的人。
對於這道題目,會樹剖的都會做(不會別說會樹剖),其主要任務是用樹剖維護區間和,支援區間、單點修改。
我的**這次主要就是卡在這裡了。
首先我們要明確每個變數陣列的意義,並且明確他們下表的意義。
int siz[102020]; //ac**:子樹大小 (用樹剖前的編號存)
int faz[102020]; //
父親節點 (用樹剖前的編號存)
int dep[102020]; //
節點深度 (用樹剖前的編號存)
int son[102020]; //
重孩子的編號 (用樹剖前的編號存)
int tid[102020]; //
樹剖後的編號 (用樹剖前的編號存)
int tva[102020]; //
樹剖後的權值 (用樹剖後的編號存)
int top[102020]; //
所在重鏈的鏈首 (用樹剖前的編號存)
int val[102020]; //
樹剖前的權值 (用樹剖前的編號存)
#include #include#include
#include
#define int long longinline
void read(int &x)
struct
edge
e[201020
];int
n, m, x, y, z, cnt, nid, opt;
int f[102020
];int siz[102020
];int faz[102020
];int dep[102020
];int son[102020
];int tid[102020
];int tva[102020
];int top[102020
];int val[102020
];void addedge(int x, int
y)//
first operation
void dfs0(int u, int father, int
deep)
}void dfs1(int u, int
head)
//segment tree
#define root 1, 1, n
#define lson u << 1, l, mid
#define rson u << 1 | 1, mid + 1, r
#define ls u << 1
#define rs u << 1 | 1
struct
tree
t[402020
];void update(int
u) void build(int u, int l, int
r)
int mid = (l + r) >> 1
; build(lson);
build(rson);
update(u);
}void pushdown(int
u)void add(int u, int l, int r, int c, int x, int
y) pushdown(u);
int mid = (l + r) >> 1
;
if (y >mid) add(rson, c, x, y);
if (x <=mid) add(lson, c, x, y);
update(u);
}int query(int u, int l, int r, int x, int
y)//
break the tree
void tsum(int x, int
y)
if (dep[x] > dep[y]) x ^= y, y ^= x, x ^=y;
ans +=query(root, tid[x], tid[y]);
printf(
"%lld\n
", ans);
}#undef int
intmain()
dfs0(
1, 0, 1
); dfs1(
1, 1
); build(root);
for (int i = 1; i <= m; ++i)
else
if (opt == 2
)
else
if (opt == 3
) tsum(
1, x);}}
洛谷 3178 樹上操作
有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 輸入格式 第一行包含兩個整數 n,m 表示點數和運算元。接下來一行 n 個整數,表示樹中節點的初始權值。接下來 n 1 行每行兩個正整數 from,to 表示該樹中存在一條邊 from,to 再接下來 m 行,每行分...
洛谷 3178 HAOI2015 樹上操作
題目描述 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數...
洛谷P3178 HAOI2015 樹上操作
有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數和運算元。...