【前缀和与差分 C/C++】洛谷 P8218 求区间和

2025 - 03 - 09 - 第 72 篇
Author: 郑龙浩 / 仟濹
【前缀和与差分 C/C++】

文章目录

洛谷 P8218 求区间和

题目描述

给定 n n n 个正整数组成的数列 a 1 , a 2 , ⋯   , a n a_1, a_2, \cdots, a_n a1,a2,⋯,an 和 m m m 个区间 [ l i , r i ] [l_i,r_i] [li,ri],分别求这 m m m 个区间的区间和。

对于所有测试数据, n , m ≤ 1 0 5 , a i ≤ 1 0 4 n,m\le10^5,a_i\le 10^4 n,m≤105,ai≤104

输入格式

第一行,为一个正整数 n n n 。

第二行,为 n n n 个正整数 a 1 , a 2 , ⋯   , a n a_1,a_2, \cdots ,a_n a1,a2,⋯,an

第三行,为一个正整数 m m m 。

接下来 m m m 行,每行为两个正整数 l i , r i l_i,r_i li,ri ,满足 1 ≤ l i ≤ r i ≤ n 1\le l_i\le r_i\le n 1≤li≤ri≤n

输出格式

共 m m m 行。

第 i i i 行为第 i i i 组答案的询问。

输入输出样例 #1

输入 #1

复制代码
4
4 3 2 1
2
1 4
2 3

输出 #1

复制代码
10
5

说明/提示

样例解释:第 1 1 1 到第 4 4 4 个数加起来和为 10 10 10。第 2 2 2 个数到第 3 3 3 个数加起来和为 5 5 5。

对于 50 % 50 \% 50% 的数据: n , m ≤ 1000 n,m\le 1000 n,m≤1000;

对于 100 % 100 \% 100% 的数据: 1 ≤ n , m ≤ 1 0 5 1 \le n, m\le 10^5 1≤n,m≤105, 1 ≤ a i ≤ 1 0 4 1 \le a_i\le 10^4 1≤ai≤104

思路

典型的的一维前缀和做法,不做具体的描述了。

我已将常规的一维前缀和笔记详细记录,具体内容可见我的博客,如下

一维前缀和算法

https://blog.csdn.net/m0_60605989/article/details/146117026?fromshare=blogdetail\&sharetype=blogdetail\&sharerId=146117026\&sharerefer=PC\&sharesource=m0_60605989\&sharefrom=from_link

代码

cpp 复制代码
// 洛谷P8218求区间和
// Author: 郑龙浩 / 仟濹
// Time: 2025-03-09
// 这道题是一个明显的一维前缀和
#include <bits/stdc++.h>
using namespace std;
// 列表
vector <int> arr;
// 前缀和数组
vector <int> sum;
int num, m;
// 计算区间和的函数 - 利用前缀和
int get_sum(int left, int right){
    int ans;
    // 注意判断,如果left是0,0-1 == -1,没有这个下标,不合法,应该特判
    if (left == 0)  return sum[right];
    // 正常套用公式即可
    ans = sum[right] - sum[left - 1];
    return ans;
}
int main( void ){
    cin >> num;
    arr.resize(num); // 设置 arr 原数列大小
    sum.resize(num); // 设置 sum 前缀和 大小
    // 输入数列
    for (int i = 0; i < num; i ++)
        cin >> arr[i];
    cin >> m;
    // 计算前缀和
    sum[0] = arr[0];
    for(int i = 1; i < num; i ++){
        sum[i] = sum[i - 1] + arr[i];
    }
    int left, right;
    // 输入 m 个区间,边输入边运算
    for (int i = 0; i < m; i ++){
        cin >> left >> right; // 输入的是第几个,而不是下标
        left -= 1; // 变为下标
        right -= 1; // 变为下标
        cout << get_sum(left, right) << endl;
    }
    return 0;
}
相关推荐
Miraitowa_cheems12 分钟前
LeetCode算法日记 - Day 81: 最大子数组和
java·数据结构·算法·leetcode·决策树·职场和发展·深度优先
Jm_洋洋15 分钟前
【Linux系统编程】程序替换:execve(execl、execlp、execle、execv、execvp、execvpe)
linux·运维·c语言·开发语言·程序人生
小莞尔31 分钟前
【51单片机】【protues仿真】基于51单片机秒表计时器系统(带存储)
c语言·stm32·单片机·嵌入式硬件·物联网·51单片机
冯诺依曼的锦鲤37 分钟前
算法练习:前缀和专题
开发语言·c++·算法
闭着眼睛学算法1 小时前
【双机位A卷】华为OD笔试之【哈希表】双机位A-跳房子I【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解
java·c语言·c++·python·算法·华为od·散列表
代码改善世界1 小时前
C语言内存机制深度解析:指针运算、数组与字符串实战指南
c语言
开发者驿站1 小时前
2025年保姆级C++环境配置教程(Windows/macOS双平台)
c++·windows·macos
辰尘_星启1 小时前
『CMake』关于使用CMake构建项目时的现代/传统指令
c++·架构·系统·cmake·项目·构建
自信150413057592 小时前
初学者小白复盘15之指针(4)
c语言·数据结构·算法
郝学胜-神的一滴2 小时前
Cesium绘制线:从基础到高级技巧
前端·javascript·程序人生·线性代数·算法·矩阵·图形渲染