进阶数据结构应用-一个简单的整数问题2(Fenwick-Tree 解法)

目录

题目-一个简单的整数问题2

问题分析

两个操作

  • 区间加数值
  • 区间查询

首先, 借用一个简单的整数问题思想, 在区间加法 的情况下, 可以将原数组转化为差分数组, 进行区间修改操作

区间查询操作, 可以转化为求前缀和 问题, 因为只要知道了前缀和 , 就知道了当前区间和

假设希望计算 ∑ i = 1 n a i \sum _{i = 1} ^ n a_i ∑i=1nai, 将其用差分序列展开得到

∑ i = 1 n ∑ j = 1 n b j \sum _{i = 1} ^ n \sum _{j = 1} ^ n b_j i=1∑nj=1∑nbj

尝试将上述公式展开为表格, 发现可以将表格补齐, 补齐后的结果
( k + 1 ) ⋅ ( b 1 + b 2 + . . . + b k ) − ( 1 ⋅ b 1 + 2 ⋅ b 2 + . . . + k ⋅ b k ) (k + 1) \cdot (b_1 + b_2 + ... + b_k) - (1 \cdot b_1 + 2 \cdot b_2 + ... + k \cdot b_k) (k+1)⋅(b1+b2+...+bk)−(1⋅b1+2⋅b2+...+k⋅bk)

后面的一段是 i ⋅ b i i \cdot b_i i⋅bi的前缀和

可以使用个树状数组一个维护 b i b_i bi一个维护 i ⋅ b i i \cdot b_i i⋅bi

算法步骤

  • 建立两个树状数组
  • 初始化树状数组
  • 修改操作需要同步修改两个树状数组
  • 查询第二个树状数组

因为 A i ≤ 1 0 9 A_i \le 10 ^ 9 Ai≤109, 计算前缀和 需要开 l o n g    l o n g long \; long longlong

代码实现

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N = 1e5 + 10;

int n, m;
int w[N];
LL tr1[N], tr2[N];

int lowbit(int x) {
    return x & -x;
}

void modify(LL tr[], int u, LL val) {
    for (int i = u; i <= n; i += lowbit(i)) tr[i] += val;
}

LL get(LL tr[], int u) {
    LL ans = 0;
    for (int i = u; i; i -= lowbit(i)) ans += tr[i];
    return ans;
}

LL calc(int k) {
    LL ans = (k + 1) * get(tr1, k) - get(tr2, k);
    return ans;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for (int i = 1; i <= n; ++i) cin >> w[i];

    for (int i = 1; i <= n; ++i) {
        modify(tr1, i, (LL) w[i] - w[i - 1]);
        modify(tr2, i, (LL) i * (w[i] - w[i - 1]));
    }

    while (m--) {
        char c;
        cin >> c;

        int l, r, val;
        if (c == 'C') {
            cin >> l >> r >> val;
            modify(tr1, l, val);
            modify(tr1, r + 1, -val);
            modify(tr2, l, (LL) l * val);
            modify(tr2, r + 1, (LL) (r + 1) * -val);
        }
        else {
            cin >> l >> r;
            LL ans = calc(r) - calc(l - 1);
            cout << ans << '\n';
        }
    }

    return 0;
}
相关推荐
无极低码2 小时前
ecGlypher新手安装分步指南(标准化流程)
人工智能·算法·自然语言处理·大模型·rag
软件算法开发2 小时前
基于海象优化算法的LSTM网络模型(WOA-LSTM)的一维时间序列预测matlab仿真
算法·matlab·lstm·一维时间序列预测·woa-lstm·海象优化
罗超驿3 小时前
独立实现双向链表_LinkedList
java·数据结构·链表·linkedlist
superior tigre3 小时前
22 括号生成
算法·深度优先
努力也学不会java4 小时前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
旖-旎4 小时前
二分查找(x的平方根)(4)
c++·算法·二分查找·力扣·双指针
ECT-OS-JiuHuaShan4 小时前
朱梁万有递归元定理,重构《易经》
算法·重构
智者知已应修善业5 小时前
【51单片机独立按键控制数码管移动反向,2片74CH573/74CH273段和位,按键按下保持原状态】2023-3-25
经验分享·笔记·单片机·嵌入式硬件·算法·51单片机
khddvbe5 小时前
C++并发编程中的死锁避免
开发语言·c++·算法
C羊驼5 小时前
C语言:两天打鱼,三天晒网
c语言·经验分享·笔记·算法·青少年编程