1 条题解
-
0
#include <bits/stdc++.h> using namespace std; using ll = long long; const int MAXN = 1e5 + 10; // 数组最大长度 ll n; // 全局变量,表示数列长度 vector<ll> a(MAXN); // 原始数组(用于存储初始值) vector<ll> tree(MAXN); // 树状数组(维护动态前缀和) /** * 计算lowbit值:提取一个数二进制中最低位的1及其后面的0 * 例如:lowbit(6) = 2 (6的二进制是110,最低位10对应的值是2) */ ll lowbit(ll i) { return i & -i; // 通过补码特性快速计算 } /** * 向树状数组中的位置i增加x(并更新所有受影响的管理区间) * @param i 需要更新的位置(1-based) * @param x 增加的值 */ void add(ll i, ll x) { while (i <= n) { // 从i开始向上更新所有父区间 tree[i] += x; // 当前区间和增加x i += lowbit(i); // 跳转到下一个管理更大区间的位置 /* * 例如:当i=2(二进制10)时: * lowbit(2)=2 → i跳到4(100) * 这意味着tree[2]管理[1,2],而tree[4]管理[1,4] */ } } /** * 查询前i个元素的前缀和 * @param i 查询的结束位置(1-based) * @return 前i个元素的和 */ ll sum(ll i) { ll res = 0; while (i > 0) { // 从i开始向下累加所有子区间 res += tree[i]; // 累加当前区间的和 i -= lowbit(i); // 跳转到前一个未被覆盖的区间起点 /* * 例如:当i=7(二进制111)时: * lowbit(7)=1 → i跳到6(110) * lowbit(6)=2 → i跳到4(100) * lowbit(4)=4 → i跳到0(终止) * 最终结果 = tree[7] + tree[6] + tree[4] */ } return res; } int main() { ios::sync_with_stdio(false), cin.tie(nullptr); // 加速输入输出 ll m; cin >> n >> m; // 输入数列长度n和操作次数m // 初始化:读取原始数组并构建树状数组 for (int i = 1; i <= n; i++) { cin >> a[i]; // 读取初始值 add(i, a[i]); // 将值加入树状数组 } // 处理m个操作 while (m--) { ll op, x, y; cin >> op >> x >> y; if (op == 1) { // 操作1:将第x个元素的值增加y add(x, y); } else { // 操作0:查询区间[x,y]的和(通过前缀和差分计算) cout << sum(y) - sum(x - 1) << "\n"; } } }
- 1
信息
- ID
- 991
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 9
- 标签
- 递交数
- 10
- 已通过
- 4
- 上传者