当前位置: 首页 > article >正文

一维二维前缀和、差分,c++

前缀和(Prefix Sum)是一种常用的预处理技术,用于快速计算数组中任意区间的和。前缀和的核心思想是通过预处理,将区间和的查询时间复杂度从 (O(n)) 降低到 (O(1))。

以下是前缀和的模板和示例:


1. 一维前缀和

1.1 模板

#include <iostream>
#include <vector>

// 计算前缀和
std::vector<int> computePrefixSum(const std::vector<int>& nums) {
    int n = nums.size();
    std::vector<int> prefix(n + 1, 0); // prefix[0] = 0

    for (int i = 1; i <= n; i++) {
        prefix[i] = prefix[i - 1] + nums[i - 1];
    }

    return prefix;
}

// 查询区间和
int queryRangeSum(const std::vector<int>& prefix, int l, int r) {
    return prefix[r + 1] - prefix[l];
}

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};

    // 计算前缀和
    std::vector<int> prefix = computePrefixSum(nums);

    // 查询区间和
    int sum1 = queryRangeSum(prefix, 1, 3); // 2 + 3 + 4 = 9
    int sum2 = queryRangeSum(prefix, 0, 4); // 1 + 2 + 3 + 4 + 5 = 15

    std::cout << "Sum of [1, 3]: " << sum1 << std::endl;
    std::cout << "Sum of [0, 4]: " << sum2 << std::endl;

    return 0;
}

输出:

Sum of [1, 3]: 9
Sum of [0, 4]: 15

1.2 应用场景

  • 区间和查询:快速计算任意区间的和。
  • 差分数组:结合差分数组,可以高效处理区间更新操作。

2. 二维前缀和

2.1 模板

#include <iostream>
#include <vector>

// 计算二维前缀和
std::vector<std::vector<int>> compute2DPrefixSum(const std::vector<std::vector<int>>& matrix) {
    int rows = matrix.size();
    int cols = matrix[0].size();

    std::vector<std::vector<int>> prefix(rows + 1, std::vector<int>(cols + 1, 0));

    for (int i = 1; i <= rows; i++) {
        for (int j = 1; j <= cols; j++) {
            prefix[i][j] = prefix[i - 1][j] + prefix[i][j - 1] - prefix[i - 1][j - 1] + matrix[i - 1][j - 1];
        }
    }

    return prefix;
}

// 查询子矩阵和
int querySubmatrixSum(const std::vector<std::vector<int>>& prefix, int x1, int y1, int x2, int y2) {
    return prefix[x2 + 1][y2 + 1] - prefix[x1][y2 + 1] - prefix[x2 + 1][y1] + prefix[x1][y1];
}

int main() {
    std::vector<std::vector<int>> matrix = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    // 计算二维前缀和
    auto prefix = compute2DPrefixSum(matrix);

    // 查询子矩阵和
    int sum1 = querySubmatrixSum(prefix, 0, 0, 1, 1); // 1 + 2 + 4 + 5 = 12
    int sum2 = querySubmatrixSum(prefix, 1, 1, 2, 2); // 5 + 6 + 8 + 9 = 28

    std::cout << "Sum of submatrix [0,0] to [1,1]: " << sum1 << std::endl;
    std::cout << "Sum of submatrix [1,1] to [2,2]: " << sum2 << std::endl;

    return 0;
}

输出:

Sum of submatrix [0,0] to [1,1]: 12
Sum of submatrix [1,1] to [2,2]: 28

2.2 应用场景

  • 子矩阵和查询:快速计算任意子矩阵的和。
  • 图像处理:用于计算图像中某个区域的总和或平均值。

3. 前缀和与差分数组的结合

3.1 差分数组模板

差分数组是前缀和的逆操作,用于高效处理区间更新。

#include <iostream>
#include <vector>

// 区间更新
void rangeUpdate(std::vector<int>& diff, int l, int r, int val) {
    diff[l] += val;
    if (r + 1 < diff.size()) {
        diff[r + 1] -= val;
    }
}

// 获取最终数组
std::vector<int> getFinalArray(const std::vector<int>& diff) {
    std::vector<int> result(diff.size() - 1, 0);
    result[0] = diff[0];
    for (int i = 1; i < result.size(); i++) {
        result[i] = result[i - 1] + diff[i];
    }
    return result;
}

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};
    std::vector<int> diff(nums.size() + 1, 0);

    // 区间更新
    rangeUpdate(diff, 1, 3, 10); // 对 [1, 3] 区间加 10

    // 获取最终数组
    auto result = getFinalArray(diff);

    // 输出结果
    std::cout << "Final Array: ";
    for (int num : result) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出:

Final Array: 1 12 13 14 5 

3.2 应用场景

  • 区间更新:对数组的某个区间进行统一加减操作。
  • 多次更新后查询:在多次区间更新后,快速获取最终数组。

4. 总结

  • 一维前缀和:用于快速计算一维数组的区间和。
  • 二维前缀和:用于快速计算二维矩阵的子矩阵和。
  • 差分数组:用于高效处理区间更新操作。

http://www.kler.cn/a/526858.html

相关文章:

  • Python - Quantstats量化投资策略绩效统计包 - 详解
  • 2025一区新风口:小波变换+KAN!速占!
  • C++ 堆栈分配的区别
  • 240. 搜索二维矩阵||
  • ping命令详解Type 8和0 或者Type 3
  • 全程Kali linux---CTFshow misc入门(14-24)
  • 二叉树的遍历
  • pytorch实现变分自编码器
  • git 删除子模块 submodule 的步骤
  • AI编程:cursor使用教程
  • stm32硬件实现与w25qxx通信
  • java日志框架详解-Log4j2
  • Workbench 中的热源仿真
  • 01.04、回文排序
  • 常用的 ASCII 码表字符
  • 如何获取Springboot项目运行路径 (idea 启动以及打包为jar均可) 针对无服务器容器新建上传文件路径(适用于win 与 linunix)
  • 【分析某音乐网站】分析一款音乐网站,并实现无限制的下载当前网站里所有的音乐
  • SpringCloud系列教程:微服务的未来(十九)请求限流、线程隔离、Fallback、服务熔断
  • 【AI】DeepSeek 概念/影响/使用/部署
  • S4 HANA税码科目确定(OB40)
  • 7 Spark 底层执行原理
  • CentOs9新手教程
  • rust如何操作oracle
  • pytorch基于GloVe实现的词嵌入
  • C++计算特定随机操作后序列元素乘积的期望
  • w182网上服装商城的设计与实现