1 条题解
-
1
#include<bits/stdc++.h> using namespace std; // 定义数组的最大长度 const int N = 200005; // 存储原始数组 long long a[N]; // 记录每一块的增加值(懒标记),用于延迟更新块内元素的值 long long bval[N]; // 记录每一块的总和,不包含 bval 中的增加值 long long bsum[N]; // 数组的长度 int n; // 操作的数量 int m; // 块的大小 int bsize; // 修改操作函数,用于将区间 [l, r] 内的所有值增加 val void modify(int l, int r, int val) { // 计算区间左端点 l 所在的块编号 int li = ceil(1.0 * l / bsize); // 计算区间右端点 r 所在的块编号 int ri = ceil(1.0 * r / bsize); // 遍历包含在区间 [l, r] 内的所有块 for (int j = li; j <= ri; j++) { // 计算当前块的左端点 int ll = (j - 1) * bsize + 1; // 计算当前块的右端点,不能超过数组的最大长度 int rr = min(j * bsize, n); // 如果当前块完全包含在区间 [l, r] 内 if (l <= ll && rr <= r) { // 直接将该块的增加值 bval[j] 增加 val,不更新块内每个元素的值 bval[j] += val; } else { // 如果当前块部分包含在区间 [l, r] 内 // 遍历当前块内的所有元素 for (int k = ll; k <= rr; k++) { // 如果当前元素在区间 [l, r] 内 if (l <= k && k <= r) { // 将该元素的值增加 val a[k] += val; // 更新该块的总和 bsum[j] bsum[j] += val; } } } } } // 查询操作函数,用于计算区间 [l, r] 内所有元素的和 long long query(int l, int r) { // 计算区间左端点 l 所在的块编号 int li = ceil(1.0 * l / bsize); // 计算区间右端点 r 所在的块编号 int ri = ceil(1.0 * r / bsize); // 初始化查询结果为 0 long long ans = 0; // 遍历包含在区间 [l, r] 内的所有块 for (int j = li; j <= ri; j++) { // 计算当前块的左端点 int ll = (j - 1) * bsize + 1; // 计算当前块的右端点,不能超过数组的最大长度 int rr = min(j * bsize, n); // 如果当前块完全包含在区间 [l, r] 内 if (l <= ll && rr <= r) { // 将该块的总和 bsum[j] 加上该块的增加值(bval[j] 乘以块内元素的数量)累加到 ans 中 ans += bsum[j] + bval[j] * (rr - ll + 1); } else { // 如果当前块部分包含在区间 [l, r] 内 // 遍历当前块内的所有元素 for (int k = ll; k <= rr; k++) { // 如果当前元素在区间 [l, r] 内 if (l <= k && k <= r) { // 将该元素的值加上该块的增加值累加到 ans 中 ans += bval[j] + a[k]; } } } } return ans; } int main() { // 读取数组的长度 n 和操作的数量 m cin >> n >> m; // 计算块的大小,通常取 sqrt(n) bsize = floor(sqrt(n)); // 初始化数组和块的总和 for (int i = 1; i <= n; i++) { // 读取数组的第 i 个元素 cin >> a[i]; // 将该元素累加到其所属块的总和 bsum 中 bsum[(int)ceil(1.0 * i / bsize)] += a[i]; } // 处理 m 次操作 for (int i = 1; i <= m; i++) { // 操作类型(0 表示修改操作,1 表示查询操作) int op; // 区间的左端点 int l; // 区间的右端点 int r; // 读取操作类型、区间左端点和区间右端点 cin >> op >> l >> r; if (op == 0) { // 如果是修改操作 // 要增加的值 int val; // 读取要增加的值 cin >> val; // 调用 modify 函数进行修改操作 modify(l, r, val); } else { // 如果是查询操作 // 调用 query 函数进行查询操作,并输出结果 cout << query(l, r) << endl; } } return 0; }
信息
- ID
- 2048
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 30
- 已通过
- 10
- 上传者