dfs序线段树

dfs序线段树

1.树上操作

思路

遍历一整棵树,记录一下节点 u 的所对应的子树的节点数 sizu 以及 dfsdfnu

根据整棵树的 dfs 序,我们可以把树变成了一个序列

再维护线段树,update(l,r,x) 表示将 [l,r] 上值加上 x.

query(l,r) 表示 l,r 上的区间和

操作 1 执行 update(dfna,dfna+sizea1,x)

操作 2 执行 query(dfna,dfna+siza1,x)

#include <bits/stdc++.h> #define ls p << 1 #define rs p << 1 | 1 using namespace std; const int N = 4e6 + 10, M = N * 2; typedef long long ll; int e[M], ne[M], idx, h[N], w[N]; int n, m, r, x; int dfn[N], cnt, vis[N]; int st[N], ed[N]; struct node { ll s, add; } tr[N]; void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; } void dfs(int u) { vis[u] = 1; dfn[++cnt] = w[u]; st[u] = cnt; for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (!vis[j]) dfs(j); } ed[u] = cnt; } void build(int p, int l, int r) { if (l == r) { tr[p].s = dfn[l]; return; } int mid = (l + r) >> 1; build(ls, l, mid); build(rs, mid + 1, r); tr[p].s = tr[ls].s + tr[rs].s; } void pushdown(int p, int l, int r) { int mid = (l + r) >> 1; tr[ls].s += tr[p].add * (mid - l + 1); tr[ls].add += tr[p].add; tr[rs].s += tr[p].add * (r - (mid + 1) + 1); tr[rs].add += tr[p].add; tr[p].add = 0; } void update(int p, int l, int r, int ql, int qr, int x) { if (ql <= l && r <= qr) { tr[p].s += (1ll) * (r - l + 1) * x; tr[p].add += x; return; } pushdown(p, l, r); int mid = (l + r) >> 1; if (ql <= mid) update(ls, l, mid, ql, qr, x); if (qr > mid) update(rs, mid + 1, r, ql, qr, x); tr[p].s = tr[ls].s + tr[rs].s; } ll query(int p, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) return tr[p].s; pushdown(p, l, r); int mid = (l + r) >> 1; ll ans = 0; if (ql <= mid) ans += query(ls, l, mid, ql, qr); if (qr > mid) ans += query(rs, mid + 1, r, ql, qr); return ans; } int main() { memset(h, -1, sizeof(h)); cin >> n >> m >> r; for (int i = 1; i <= n; i++) cin >> w[i]; for (int i = 1; i < n; i++) { int a, b; cin >> a >> b; add(a, b), add(b, a); } vis[0] = 1; dfs(r); build(1, 1, n); for (int i = 1; i <= m; i++) { int k, a; cin >> k >> a; if (k == 1) { cin >> x; update(1, 1, n, st[a], ed[a], x); } else cout << query(1, 1, n, st[a], ed[a]) << '\n'; } return 0; }

__EOF__

本文作者ljfyyds
本文链接https://www.cnblogs.com/ljfyyds/p/17639866.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   ljfyyds  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示