HDU 3966 Aragorn's Story 树链剖分 线段树
最基础的树链剖分啦,存下来当模板
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
using namespace std;
const int maxn = 5e4 + 10;
int head[maxn], nxt[maxn << 1], v[maxn << 1], ecnt;
int N, M, P, sval[maxn], tcnt, Rank[maxn];
int siz[maxn], top[maxn], son[maxn], dep[maxn], tid[maxn], fa[maxn];
int lazy[maxn << 2], val[maxn << 2];
void init() {
memset(head, -1, sizeof(head));
ecnt = tcnt = 0;
}
void add_edge(int uu, int vv) {
v[ecnt] = vv; nxt[ecnt] = head[uu]; head[uu] = ecnt++;
}
void dfs1(int now, int f, int now_dep) {
siz[now] = 1; son[now] = -1; dep[now] = now_dep; fa[now] = f;
for(int i = head[now]; ~i; i = nxt[i]) if(v[i] != f) {
dfs1(v[i], now, now_dep + 1);
siz[now] += siz[v[i]];
if(son[now] == -1 || siz[v[i]] > siz[son[now]]) {
son[now] = v[i];
}
}
}
//tp 是当前链顶点的编号
void dfs2(int now, int tp) {
top[now] = tp; tid[now] = ++tcnt; Rank[tid[now]] = now;
if(siz[now] == 1) return;
dfs2(son[now], tp);
for(int i = head[now]; ~i; i = nxt[i]) if(v[i] != fa[now] && v[i] != son[now]) {
dfs2(v[i], v[i]);
}
}
void pushup(int rt) {
val[rt] = max(val[rt << 1], val[rt << 1 | 1]);
}
void pushdown(int rt, int l, int r) {
if(lazy[rt] == 0) return;
int mid = l + r >> 1, lc = rt << 1, rc = rt << 1 | 1;
lazy[lc] += lazy[rt]; lazy[rc] += lazy[rt];
val[lc] += lazy[rt] * (mid - l + 1);
val[rc] += lazy[rt] * (r - mid);
lazy[rt] = 0;
}
void build(int rt, int l, int r) {
int mid = l + r >> 1;
lazy[rt] = 0;
if(l == r) val[rt] = sval[Rank[l]];
else {
build(lson); build(rson);
pushup(rt);
}
}
int query(int rt, int l, int r, int x) {
if(l == r) return val[rt];
int mid = l + r >> 1;
pushdown(rt, l, r);
if(x <= mid) return query(lson, x);
else return query(rson, x);
}
void update(int rt, int l, int r, int ql, int qr, int Val) {
if(ql <= l && qr >= r) {
val[rt] += Val * (r - l + 1);
lazy[rt] += Val;
}
else {
int mid = l + r >> 1;
pushdown(rt, l, r);
if(ql <= mid) update(lson, ql, qr, Val);
if(qr > mid) update(rson, ql, qr, Val);
pushup(rt);
}
}
//树链剖分 区间修改
void Change(int x, int y, int Val) {
while(top[x] != top[y]) {
//先更新深度大的链
if(dep[top[x]] < dep[top[y]]) swap(x, y);
update(1, 1, N, tid[top[x]], tid[x], Val);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
update(1, 1, N, tid[x], tid[y], Val);
}
int main() {
while(scanf("%d%d%d", &N, &M, &P) != EOF) {
init();
for(int i = 1; i <= N; i++) scanf("%d", &sval[i]);
for(int i = 0; i < M; i++) {
int a, b; scanf("%d%d", &a, &b);
add_edge(a, b); add_edge(b, a);
}
dfs1(1, 1, 1); dfs2(1, 1); build(1, 1, N);
for(int i = 0; i < P; i++) {
char cmd; scanf(" %c", &cmd);
if(cmd == 'Q') {
int pos; scanf("%d", &pos);
printf("%d\n", query(1, 1, N, tid[pos]));
}
else {
int ql, qr, Val; scanf("%d%d%d", &ql, &qr, &Val);
if(cmd == 'D') Val = -Val;
Change(ql, qr, Val);
}
}
}
return 0;
}

浙公网安备 33010602011771号