本文共 2203 字,大约阅读时间需要 7 分钟。
树状数组之区间最值
树状数组是一种基于位操作的数据结构,常用于解决动态区间最值问题。其核心原理基于以下性质:每个节点代表一个区间,该区间的最大值可能来自其左子节点。通过将元素依次添加到树状数组的尾部,树状数组可以在O(log n)时间内完成插入和查询操作。
树状数组的推送操作如下:
void push(int pos) { int i, lb = lowbit(pos); c[pos] = a[pos]; for (i = 1; i < lb; i++) { c[pos] = max(c[pos], c[pos - i]); }} 该函数在指定位置插入元素,并向上更新路径上的每个父节点的最大值。
更新操作如下:
void update(int pos, int v) { int i, lb; c[pos] = a[pos] = v; lb = lowbit(pos); for (i = 1; i < lb; i++) { c[pos] = max(c[pos], c[pos - i]); } for (pos = pos + lowbit(pos); pos <= n; pos += lowbit(pos)) { if (c[pos] < c[pos - lowbit(pos)]) { c[pos] = c[pos - lowbit(pos)]; } else { break; } }} 查询区间最值的逻辑如下:
int query(int x, int y) { int res = -1; while (x <= y) { int nx = y - lowbit(y) + 1; if (nx >= x) { res = max(res, c[y]); y = nx - 1; } else { res = max(res, a[y]); y--; } } return res;} const int maxn = 1e6 + 5, maxe = 1e6 + 5;int n, m;int N = maxn;int a[maxn], c[maxn];inline int lowbit(int x) { return x & -x;}inline int fa(int p) { return p + lowbit(p);}inline int left(int p) { return p - lowbit(p);}inline int g(int a, int b) { return a > b ? a : b;}void update_by_child(int p, int v) { c[p] = a[p] = v; int lb = lowbit(p); for (int i = 1; i < lb; i++) { c[p] = max(c[p], c[pos - i]); }}void update(int p, int v) { update_by_child(p, v); int t = c[p]; for (p = fa(p); p <= N; p = fa(p)) { if (c[p] > t) { t = c[p]; } else { break; } }}int query(int l, int r) { int ret = a[l]; for (; l <= r; ) { int next = left(r) + 1; if (next >= l) { ret = max(ret, c[r]); r = next - 1; } else { ret = max(ret, a[r]); r--; } } return ret;} hdu[1754] I Hate It
该解决方案在时间复杂度方面保证了效率,特别适用于大规模数据处理场景。
转载地址:http://cdaiz.baihongyu.com/