Technology Sharing

Algorithm - Prefix Sum

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Table of contents

【Template】One-dimensional prefix sum

【Template】Two-dimensional prefix sum

Find the center index of an array

Product of arrays other than itself

Matrix area and


【Template】One-dimensional prefix sum

If we use brute force solution,The array must be traversed once each time, for a total of q times,sotime complexityToo high, then we construct a prefix sum arrayThe sum of each interval in the 1 - n interval is stored in, we need the first n items and directly access the dp prefix and the subscript position of the array. The code is as follows:

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. // 读入数据
  7. int n, q; cin >> n >> q;
  8. // n + 1 添加了虚拟节点0
  9. vector<int> arr(n + 1); // 默认全部为0
  10. for (int i = 1; i <= n; i++)
  11. cin >> arr[i];
  12. // 预处理出一个前缀和数组
  13. vector<long long> dp(n + 1); // 防止溢出
  14. for (int i = 1; i <= n; i++)
  15. dp[i] = dp[i - 1] + arr[i];
  16. // 使用前缀和数组
  17. int l = 0, r = 0;
  18. while (q--)
  19. {
  20. cin >> l >> r;
  21. cout << dp[r] - dp[l - 1] << endl;
  22. }
  23. return 0;
  24. }

【Template】Two-dimensional prefix sum

PreprocessingA prefix sum matrix,All elements from (1, 1) to (i, j) andExisting in this dp array, throughArea calculation method, find the final answer, the code is as follows:

  1. int main()
  2. {
  3. // 读入数据
  4. int n, m, q; cin >> n >> m >> q;
  5. vector<vector<int>> arr(n + 1, vector<int>(m + 1));
  6. for (int i = 1; i <= n; i++)
  7. for (int j = 1; j <= m; j++)
  8. cin >> arr[i][j];
  9. // 预处理一个前缀和数组
  10. vector<vector<long long>> dp(n + 1, vector<long long>(m + 1)); // 防止溢出
  11. for (int i = 1; i <= n; i++)
  12. for (int j = 1; j <= m; j++)
  13. dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + arr[i][j] - dp[i - 1][j - 1];
  14. // 使用前缀和数组
  15. while (q--)
  16. {
  17. int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
  18. cout << dp[x2][y2] - dp[x2][y1 - 1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1] << endl;
  19. }
  20. return 0;
  21. }

Find the center index of an array

Note the boundary conditions here.No need to open n+1 spaces for prefix and array, because there is an element in the original array to be used as the center subscript of this question, the code is as follows:

  1. class Solution {
  2. public:
  3. int pivotIndex(vector<int>& nums) {
  4. int n = nums.size();
  5. vector<int> f(n), g(n);
  6. // 预处理前缀和数组 从左向右
  7. for (int i = 1; i < n; i++)
  8. f[i] = f[i - 1] + nums[i - 1];
  9. // 预处理后缀和数组 从右向左
  10. for (int i = n - 2; i >= 0; i--)
  11. g[i] = g[i + 1] + nums[i + 1];
  12. for (int i = 0; i < n; i++)
  13. {
  14. if (g[i] == f[i])
  15. return i;
  16. }
  17. return -1;
  18. }
  19. };

Product of arrays other than itself

The meaning is similar to the previous question, but it should be noted that the boundary cases f(0) and g(n-1) should be initialized to 1 instead of 0. The code is as follows:

  1. class Solution {
  2. public:
  3. vector<int> productExceptSelf(vector<int>& nums) {
  4. int n = nums.size();
  5. vector<int> f(n), g(n), ret(n);
  6. // 处理边界情况
  7. f[0] = 1; g[n - 1] = 1;
  8. // 预处理前缀积数组 从左向右
  9. for (int i = 1; i < n; i++)
  10. f[i] = f[i - 1] * nums[i - 1];
  11. // 预处理后缀积数组 从右向左
  12. for (int i = n - 2; i >= 0; i--)
  13. g[i] = g[i + 1] * nums[i + 1];
  14. for (int i = 0; i < n; i++)
  15. ret[i] = f[i] * g[i];
  16. return ret;
  17. }
  18. };

Matrix area and

Note: The two-dimensional prefix and array must have one more row and one more column, otherwise out-of-bounds access will occur. In addition, the subscripts between the dp array and the ans array need to be adjusted to match the positions. ans[0][0] corresponds to the position dp[1][1]. The code is as follows:

  1. class Solution {
  2. public:
  3. vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
  4. int m = mat.size(), n = mat[0].size(); // m 为行 n 为列
  5. // 预处理一个二维前缀和数组 dp
  6. vector<vector<int>> dp(m + 1, vector<int>(n + 1));
  7. for (int i = 1; i <= m; i++)
  8. for (int j = 1; j <= n; j++)
  9. dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + mat[i - 1][j - 1] - dp[i - 1][j - 1];
  10. // 存放答案的二维数组 ans
  11. vector<vector<int>> ans(m, vector<int>(n));
  12. for (int i = 0; i < m; i++)
  13. {
  14. for (int j = 0; j < n; j++)
  15. {
  16. int x1 = max(0, i - k) + 1, y1 = max(0, j - k) + 1;
  17. int x2 = min(m - 1, i + k) + 1, y2 = min(n - 1, j + k) + 1;
  18. ans[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];
  19. }
  20. }
  21. return ans;
  22. }
  23. };