#include<bits/stdc++.h> using namespace std; #define int long long int read(){int x=0;char f=1,ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;} const int N=5e5+10; int n,m,a[N],c[N]; int lowbit(int x){ return x&(-x); } void add(int x,int k){ while(x<=n){ c[x]+=k; x+=lowbit(x); } return; } int sum(int x){ int res=0; while(x){ res+=c[x]; x-=lowbit(x); } return res; } signed main(){ n=read(),m=read(); for(int i=1;i<=n;++i){ a[i]=read(); add(i,a[i]-a[i-1]); } while(m--){ int op=read(); if(op==1){ int l=read(),r=read(),k=read(); add(l,k),add(r+1,-k); } else{ int x=read(); printf("%lld\n",sum(x)); } } return 0; } #include <bits/stdc++.h> using namespace std; int n, m, s[100005]; int lowbit(int x) { return x & (-x); } struct tree { int c[100005]; void init() { memset(c, 0, sizeof(c)); for (int i = 1; i <= n; i++) for (int j = i - lowbit(i) + 1; j <= i; j++) c[i] += s[j]; } void add(int x, int k) { s[x] += k; for (int i = x; i <= n; i += lowbit(i))c[i] += k; } int query(int x) { int ans = 0; for (int i = x; i > 0; i -= lowbit(i))ans += c[i]; return ans; } }a; int main() { cin >> n >> m; for (int i = 1; i <= n; i++)cin >> s[i]; a.init(); while (m--) { int bl, x, yk; cin >> bl >> x >> yk; if (bl == 1)a.add(x, yk); else cout << a.query(yk) - a.query(x - 1) << '\n'; } return 0; } 根据代码1修改代码2
时间: 2025-03-23 20:18:03 浏览: 67
通过对比两段代码可以发现它们的功能相似,都是基于树状数组(Binary Indexed Tree, BIT)实现区间更新和单点查询的操作。然而,**代码2存在一些功能缺失部分需要按照代码1的要求补充完整**。
以下是修改后的 **代码2**:
```cpp
#include <bits/stdc++.h>
using namespace std;
int n, m, s[100005];
// 计算 lowbit 值
int lowbit(int x) {
return x & (-x);
}
// 树状数组结构体
struct tree {
int c[100005]; // 存储树状数组
// 初始化树状数组
void init() {
memset(c, 0, sizeof(c)); // 清零
for (int i = 1; i <= n; ++i)
for (int j = i - lowbit(i) + 1; j <= i; ++j)
c[i] += s[j];
}
// 单点增加操作
void add(int x, int k) {
s[x] += k; // 修改原数据
for (int i = x; i <= n; i += lowbit(i))
c[i] += k; // 更新树状数组对应值
}
// 查询前缀和
int query(int x) {
int ans = 0;
for (int i = x; i > 0; i -= lowbit(i))
ans += c[i];
return ans;
}
} a;
int main() {
cin >> n >> m; // 输入元素个数和操作次数
for (int i = 1; i <= n; ++i) cin >> s[i]; // 输入初始序列
a.init(); // 初始化树状数组
while (m--) { // 按照操作次数循环处理每种请求
int op, l, r, k, x;
cin >> op; // 获取当前操作类型
if (op == 1) { // 如果是区间加法操作
cin >> l >> r >> k; // 输入左端点、右端点以及增量k
a.add(l, k); // 左端点位置增加值k
if (r + 1 <= n) // 右端点右侧第一个位置减少k
a.add(r + 1, -k);
} else { // 否则是单点查询操作
cin >> x; // 输入目标下标x
cout << a.query(x) - (x >= 2 ? a.query(x - 1) : 0) << '\n'; // 输出该位置的数值
}
}
return 0;
}
```
### 主要改动说明:
1. 添加了对 `区间加法` 的支持。
- 当读取到 `op=1` 时,表示这是一个区间的加减操作。
- 需要在指定范围内 `[l,r]` 内的所有数字都加上常量 `k`,因此分别调用两次 `add()` 函数完成此任务。
```cpp
a.add(l, k);
if (r + 1 <= n) a.add(r + 1, -k);
```
2. 调整了查询结果计算方式。
- 对于每个单点查询操作,直接使用 `query(x)` 并扣除掉左侧的部分即可得到正确的答案。
---
阅读全文
相关推荐







