【深进1.例1】求区间和
题目理解
这道题要求我们处理多个区间求和查询。给定一个长度为n的整数序列,然后有m个查询,每个查询给出一个区间[l, r],要求计算该区间内所有数的和。
解题思路
暴力解法的问题
最直观的方法是对于每个查询,都从l到r遍历数组求和。这种方法的时间复杂度是O(mn),当n和m都达到10^5时,这样的时间复杂度会导致超时(10^10次操作在大多数OJ上都会超时)。
前缀和优化
前缀和是一种预处理技术,可以让我们在O(1)时间内回答任何区间和查询。具体思路是:
- 
预处理阶段:创建一个前缀和数组s,其中s[i]表示数组前i个元素的和(a[1]到a[i])。 
- 
查询阶段:对于查询[l, r],区间和可以通过s[r] - s[l-1]计算得到。 
这样,预处理时间复杂度是O(n),每个查询处理时间是O(1),总时间复杂度优化为O(n + m),完全可以处理题目给出的数据规模。
参考代码
#include<bits/stdc++.h>
#define ll long long
#define N 100005
using namespace std;
int a[N], s[N], n, m; // 定义数组a存储原始数据,数组s存储前缀和
int main() {
    // 读取序列长度n
    cin >> n;
    
    // 读取序列并计算前缀和
    for (int i = 1; i <= n; i++) {
        cin >> a[i]; // 读取第i个元素
        s[i] = s[i - 1] + a[i]; // 计算前i个元素的和,存入s[i]
    }
    
    // 读取查询数量m
    cin>>m;
    
    // 处理每个查询
    while(m--){
        int L,R;
        cin>>L>>R; // 读取查询区间[L,R]
        // 输出区间和:前R项和减去前L-1项和
        cout<<s[R]-s[L-1]<<endl; 
    }
    return 0;
}代码细节说明
- 
数组定义:使用全局数组a和s,大小设为N=100005,满足题目数据范围要求。 
- 
前缀和计算:s[i] = s[i-1] + a[i]这个递推式是关键,它利用已计算的前缀和来快速计算新的前缀和。 
- 
查询处理:对于每个查询,直接使用前缀和数组做减法得到结果,避免了重复计算。 
- 
索引处理:注意s[L-1]的使用,因为区间包含第L个元素。 
复杂度分析
- 
时间复杂度: - 
预处理阶段:O(n)(填充前缀和数组) 
- 
查询阶段:O(m)(每个查询O(1)) 
- 
总时间复杂度:O(n + m) 
 
- 
- 
空间复杂度:O(n)(存储前缀和数组) 
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号