2 条题解

  • 1
    @ 2026-3-22 17:34:38

    为什么要出这道题!!

    • 1
      @ 2026-3-22 17:33:44

      问题分析

      这是一个典型的区间和查询问题,核心需求是高效处理大量的区间求和查询。由于 nm 都高达 10⁵,若每次查询都暴力累加(时间复杂度 O(n)),总时间复杂度会达到 O(n*m) = 10¹⁰,远超时间限制。

      最优解决方案是使用前缀和数组

      1. 预处理一个前缀和数组 prefix,其中 prefix[i] 表示前 i 段路程的总时间;
      2. 对于任意查询 [l, r],区间和 = prefix[r] - prefix[l-1]
      3. 预处理时间复杂度 O(n),单次查询时间复杂度 O(1),总时间复杂度 O(n + m),完全满足 10⁵ 级别的数据规模。

      完整C++代码实现

      #include <iostream>
      #include <vector>
      
      using namespace std;
      
      int main() {
          // 关闭同步加速cin/cout,避免大数据量下超时
          ios::sync_with_stdio(false);
          cin.tie(nullptr);
          
          int n;
          cin >> n;
          
          // 前缀和数组:prefix[0] = 0,prefix[1] = a1,prefix[2] = a1+a2,...
          vector<long long> prefix(n + 1, 0); // 用long long防止溢出
          for (int i = 1; i <= n; ++i) {
              int time;
              cin >> time;
              prefix[i] = prefix[i - 1] + time;
          }
          
          int m;
          cin >> m;
          while (m--) {
              int l, r;
              cin >> l >> r;
              // 区间[l, r]的和 = 前r项和 - 前l-1项和
              cout << prefix[r] - prefix[l - 1] << '\n'; // 用'\n'代替endl,减少刷新缓冲区开销
          }
          
          return 0;
      }
      

      代码详细解释

      1. 输入输出优化(关键!)

      ios::sync_with_stdio(false);
      cin.tie(nullptr);
      
      • ios::sync_with_stdio(false):关闭 C++ 标准输入输出与 C 标准输入输出的同步,大幅提升 cin/cout 速度;
      • cin.tie(nullptr):解除 cin 与 cout 的绑定(默认 cin 读取前会刷新 cout),进一步加速;
      • '\n' 代替 endlendl 会强制刷新输出缓冲区,而 '\n' 仅输出换行,效率更高。

      2. 前缀和数组设计

      • 前缀和数组 prefix 长度为 n+1,且 prefix[0] = 0
        • 这样设计可以统一处理 l=1 的情况(如查询 [1, r] 时,直接用 prefix[r] - prefix[0]);
        • 避免单独判断边界,简化逻辑。
      • 数据类型选择 long long
        • 最坏情况下,n=10⁵,每个 a_i=1000,总和 = 10⁵ * 1000 = 10⁸,虽然 int(最大约 2×10⁹)能容纳,但为了绝对避免溢出(如数据范围扩展),优先使用 long long

      3. 核心逻辑

      • 预处理前缀和
        prefix[i] = prefix[i - 1] + time;
        
        遍历输入的每一段路程时间,累加得到前缀和数组。
      • 处理查询
        cout << prefix[r] - prefix[l - 1] << '\n';
        
        例如查询 [2,4]
        • prefix[4] = a1+a2+a3+a4
        • prefix[1] = a1
        • 差值 = a2+a3+a4,即目标区间和。

      测试用例验证(样例1)

      输入:

      5
      1 2 3 4 5
      3
      1 3
      2 5
      1 5
      

      前缀和数组计算:

      • prefix[0] = 0
      • prefix[1] = 0 + 1 = 1
      • prefix[2] = 1 + 2 = 3
      • prefix[3] = 3 + 3 = 6
      • prefix[4] = 6 + 4 = 10
      • prefix[5] = 10 + 5 = 15

      查询处理:

      1. l=1, r=3prefix[3] - prefix[0] = 6 - 0 = 6
      2. l=2, r=5prefix[5] - prefix[1] = 15 - 1 = 14
      3. l=1, r=5prefix[5] - prefix[0] = 15 - 0 = 15; 输出结果与样例一致。

      边界情况测试

      • 单段路程查询n=1, a=[5], m=1, l=1, r=1 → 输出 5
      • 全区间查询n=10⁵,查询 l=1, r=10⁵ → 直接返回 prefix[10⁵]
      • 相邻区间查询l=r-1 → 如 l=3, r=4,返回 a3+a4

      总结

      1. 核心思路:用前缀和数组将区间和查询从 O(n) 优化到 O(1),解决大数据量下的效率问题;
      2. 关键优化:关闭 cin/cout 同步、使用 long long 防溢出、用 '\n' 代替 endl
      3. 核心公式:区间 [l, r] 的和 = 前缀和数组 prefix[r] - prefix[l-1]

      该方案是区间和查询的最优解,时间/空间复杂度均为线性,能稳定处理题目要求的 10⁵ 级数据。

      • 1

      汉堡狂热爱好者李荣轩—数据增强版

      信息

      ID
      597
      时间
      1000ms
      内存
      256MiB
      难度
      3
      标签
      递交数
      34
      已通过
      8
      上传者