Partage de technologie

Algorithme - somme de préfixes

2024-07-12

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

Table des matières

[Modèle] Somme de préfixe unidimensionnelle

[Modèle] Somme de préfixe bidimensionnelle

Trouver l'index central d'un tableau

Produit de tableaux autres que soi

somme des aires de la matrice


[Modèle] Somme de préfixe unidimensionnelle

Si nous utilisons une solution par force brute,Le tableau doit être parcouru à chaque fois, un total de q fois,donccomplexité temporelleest trop élevé, nous construisons à ce moment un tableau de somme de préfixes pourLa somme de chaque intervalle dans l'intervalle 1-n est stockée dans , vous avez besoin des n premiers éléments et d'un accès direct au préfixe dp et à la position en indice du tableau. le code s'affiche comme ci-dessous :

  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. }

[Modèle] Somme de préfixe bidimensionnelle

prétraitementune matrice de somme de préfixes quiLa somme de tous les éléments des positions (1, 1) à (i, j)existe dans ce tableau dp, viaMéthode de calcul de la superficie, pour trouver la réponse finale, le code est le suivant :

  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. }

Trouver l'index central d'un tableau

Notez les cas extrêmes iciPas besoin d'ouvrir le préfixe d'espace n+1 et le tableau, car il y a un élément dans le tableau d'origine qui doit être utilisé comme indice central de cette question. Le code est le suivant :

  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. };

Produit de tableaux autres que soi

La signification est similaire à la question précédente, mais il faut noter que les cas limites f(0) et g(n-1) doivent être initialisés à 1 au lieu de 0. Le code est le suivant :

  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. };

somme des aires de la matrice

Remarque : Le préfixe et le tableau bidimensionnels doivent avoir une ligne et une colonne supplémentaires, sinon un accès hors limites se produira. De plus, les indices doivent être ajustés entre le tableau dp et le tableau ans pour correspondre aux positions. ans[ 0 ][ 0 ] correspond à dp [ 1 ][ 1] cet emplacement. le code s'affiche comme ci-dessous :

  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. };