1.Prefix字首和【模板】

Phantasia1116發表於2024-03-06
  • [[#題目描述|題目描述]]
  • [[#輸入描述|輸入描述]]
  • [[#輸出描述|輸出描述]]
  • [[#輸入樣例1|輸入樣例1]]
  • [[#輸出樣例1|輸出樣例1]]
  • [[#暴力窮舉|暴力窮舉]]
  • [[#字首和陣列|字首和陣列]]

題目描述

給定義一個陣列a,有q次詢問,對於每次詢問:

給定兩個整數l,r,求出${a_l}$ $+$${a_{l+1}}$ + ${\dots}$ +$a_r$​的結果。

輸入描述

第一行一個整數表示樣例個數T(1≤T≤10)

對於每組樣例:

第一行22個整數n(1≤n≤105),q(1≤q≤105),分別表示陣列長度和詢問次數。

第二行n個整數,表示陣列a(−109≤$a_i$​≤109)。

接下來q行,每行兩個整數l,r(1≤l≤r≤n)表示詢問的區間。

輸出描述

對於每組樣例,一行一個整數表示答案。

輸入樣例1

2
5 3
1 2 3 4 5
1 2
2 5
3 4
7 2
-1 9 -10 8 2 6 11
1 5
2 7

輸出樣例1

3
14
7
8
26

暴力窮舉

  • 對每一個[l ,r]區間中的數都進行加和
  • 使用for迴圈進行計算
  • 最壞情況下n為10的5次方, q為10的5次方,l為1,r為10的5次方
  • 總共加和次數為10^10 數量級 對1000ms的數量級而言有點過於高了

字首和陣列

$$P_i = sum_{j=1}^i a_j = P_{i-1} + a_i$$

  • 於是便有以下的性質
  • image.png

Code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 1e5 + 9;
// 全域性陣列自動初始化為0
ll a[N], prefix[N];

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int m;
  cin >> m;
  while (m--) {
    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    for (int i = 1; i <= n; ++i) prefix[i] = prefix[i - 1] + a[i];
    while (q--) {
      int l, r;
      cin >> l >> r;
      cout << prefix[r] - prefix[l - 1] << '\n';
    }
  }
  return 0;
}

相關文章