树状数组区间更新板子

存一个树状数组区间更新的板子

ll c1[maxn];//c1维护差分数组的前缀和
ll c2[maxn], a[maxn];//c2维护c1 * (pos - 1)的前缀和
//a[i]的前缀和[1, p]可以由c1[1,2,...,p] * p - c2[1,2,...,p]表示
int n;
inline int lowbit(int x)
{
    return x & (-x);
}

void add(int p, int val)
{
    for (int i = p; i <= n; i += lowbit(i))
    {
        c1[i] += val;
        c2[i] += 1ll * val * (p - 1);
    }
}

inline void update(int l, int r, int w)
{
    add(l, w);
    add(r + 1, -w);
}

ll getSum(int p)
{
    ll ans = 0;
    for (int i = p; i > 0; i -= lowbit(i))
        ans += 1ll * p * c1[i] - c2[i];
    return ans;
}
树状数组区间更新的原理主要基于差分与前缀和的思想,通过维护原数组的差分来实现高效的区间更新和单点查询。 树状数组与线段树类似,用大节点表示一些小节点的信息,查询时只需查询大节点而非更多小节点。以维护原数组的差分来实现区间更新,每次修改只需更新边界,单点查询时对树状数组求和即可得到对应的值。 例如,对于一个数组 `a`,构建其差分数组 `d`,其中 `d[i] = a[i] - a[i - 1]`(`i > 1`),`d[1] = a[1]`。若要对区间 `[l, r]` 内的所有元素加上一个值 `c`,只需对差分数组进行修改:`d[l] += c`,`d[r + 1] -= c`。这样,在查询第 `x` 个元素的值时,只需要计算差分数组的前缀和 `sum(d[1]...d[x])` 即可得到 `a[x]` 的值。 树状数组使用 `lowbit` 函数来快速定位父节点和子节点的关系。`lowbit(x)` 用于求 `x` 的二进制表示中最后一位 1 所代表的值,其实现为 `x & -x`。在更新操作中,通过 `add` 函数更新所有包含 `x` 的父节点;在查询操作中,通过 `query` 函数求树状数组 1 到 `x` 的和。 以下是区间修改、单点查询的代码模板: ```cpp #include<iostream> using namespace std; const int N = 5e5 + 10; int n, m; int a[N], t[N]; int lowbit(int x) // 求最后一位 1 { return x & -x; } void add(int x, int c) // 所有包含 x 的父节点都要更新 { for(int i = x; i <= n; i += lowbit(i)) t[i] += c; } int query(int x) // 求树状数组 1~x 的和就是第 x 个元素的值 { int sum = 0; for(int i = x; i > 0; i -= lowbit(i)) sum += t[i]; return sum; } int main() { scanf("%d %d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); add(i, a[i] - a[i - 1]); } while(m--) { int op, x, y, c; scanf("%d", &op); if(op == 1) { scanf("%d %d %d", &x, &y, &c); add(x, c); add(y + 1, -c); } else { scanf("%d", &x); printf("%d\n", query(x)); } } return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值