C++ 算法学习——1.6 差分算法与二维差分算法

  1. 一维差分算法概述

    • 差分算法是一种用于计算序列中相邻元素之间差值的技术。
    • 在C++中,STL(标准模板库)提供了std::adjacent_difference函数来实现差分算法。
  2. std::adjacent_difference函数

    • std::adjacent_difference函数位于头文件<numeric>中。
    • 语法:std::adjacent_difference(first, last, result)
      • firstlast是定义了输入序列范围的迭代器。
      • result是存储结果的目标序列的起始位置

一维差分数组在处理连续序列中的区间更新和查询操作时非常有用。它可以帮助在常数时间复杂度内完成区间元素的增减操作,并支持常数时间复杂度的区间查询操作。以下是一维差分数组的一些主要用途和优点:

  1. 区间更新:对于原始数组中 [l, r] 区间内的元素增加 val,只需更新差分数组 diff 中 diff[l] += val 和 diff[r+1] -= val,然后再根据差分数组计算更新后的原始数组。

  2. 查询:原始数组中位置为L的元素等于差分数组中 [L]前所有元素的和 

  3. 应用领域:差分数组在处理数组序列的区间操作中广泛应用,比如处理频繁的区间修改、查询问题。

代码示例(构建): 

std::vector<int> differences(nums.size());std::adjacent_difference(nums.begin(), nums.end(), differences.begin());

  1. 二维差分算法概述

    • 二维差分算法是一种用于计算二维数组中差分的技术。
    • 通过预处理数组,可以在常数时间内计算子矩阵的增减值,而不必每次都一一计算。
  2. 实现方式

    • 我们可以使用差分数组diff表示相邻元素之间的差值关系。二维差分数组diff的构建规则如下:
  • diff[i][j] = matrix[i][j] - matrix[i-1][j] - matrix[i][j-1] + matrix[i-1][j-1]

代码示例(构建):

int **computeDifferenceArray(int **matrix, int rows, int cols) {int **diff = new int*[rows];for (int i = 0; i < rows; i++) {diff[i] = new int[cols]();}for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {diff[i][j] = matrix[i][j]; // 复制原始数组的值// 处理边界情况if (i > 0) diff[i][j] -= matrix[i - 1][j]; // 上方元素if (j > 0) diff[i][j] -= matrix[i][j - 1]; // 左方元素if (i > 0 && j > 0) diff[i][j] += matrix[i - 1][j - 1]; // 左上方元素}}return diff;
}

 代码示例(计算)://如果对原数组(x1,y1)到(x2,y2)的矩形区域整体加上a.

void updateDiffArray(int** &diff, int x1, int y1, int x2, int y2, int a, int rows, int cols) {// Check if the indices are within boundsif (x1 >= 0 && x1 < rows && y1 >= 0 && y1 < cols &&x2 >= 0 && x2 < rows && y2 >= 0 && y2 < cols) {diff[x1][y1] += a;if (x2 + 1 < rows && y1 < cols) diff[x2 + 1][y1] -= a;if (x1 < rows && y2 + 1 < cols) diff[x1][y2 + 1] -= a;if (x2 + 1 < rows && y2 + 1 < cols) diff[x2 + 1][y2 + 1] += a;} 
}

最后通过二维前缀和还原到原数组即可。


 P1. 洛谷p2367语文成绩

#include<iostream>
#include<numeric>
#include<vector>
#include<cmath>
using namespace std;
long long ans=0;
long long result=10000;int main()
{int n,q;cin>>n>>q;vector<int> nums,differs;for(int i=1;i<=n;i++){int a;cin>>a;nums.push_back(a);}differs.resize(n);//很重要,不然调用函数会访问到未分配的内存,发生越界错误adjacent_difference(nums.begin(),nums.end(),differs.begin());//for(int i=0;i<n;i++) cout<<differs[i]<<" ";for(int i=1;i<=q;i++){int left,right,value;cin>>left>>right>>value;differs[left-1]+=value;differs[right]-=value;}for(int i=0;i<n;i++){ans+=differs[i];result=fmin(ans,result);}cout<<result;return 0;
}

P2. 洛谷p3397地毯

#include<iostream>
using namespace std;int **computeDifferenceArray(int **matrix, int rows, int cols) {int **diff = new int*[rows];for (int i = 0; i < rows; i++) {diff[i] = new int[cols]();}for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {diff[i][j] = matrix[i][j]; // 复制原始数组的值// 处理边界情况if (i > 0) diff[i][j] -= matrix[i - 1][j]; // 上方元素if (j > 0) diff[i][j] -= matrix[i][j - 1]; // 左方元素if (i > 0 && j > 0) diff[i][j] += matrix[i - 1][j - 1]; // 左上方元素}}return diff;
}void updateDiffArray(int** &diff, int x1, int y1, int x2, int y2, int a, int rows, int cols) {// Check if the indices are within boundsif (x1 >= 0 && x1 < rows && y1 >= 0 && y1 < cols &&x2 >= 0 && x2 < rows && y2 >= 0 && y2 < cols) {diff[x1][y1] += a;if (x2 + 1 < rows && y1 < cols) diff[x2 + 1][y1] -= a;if (x1 < rows && y2 + 1 < cols) diff[x1][y2 + 1] -= a;if (x2 + 1 < rows && y2 + 1 < cols) diff[x2 + 1][y2 + 1] += a;} 
}int** build2DPrefixSumArray(int** matrix, int rows, int cols) {// 分配内存来存储前缀和数组int** prefixSum = new int*[rows];for (int i = 0; i < rows; i++) {prefixSum[i] = new int[cols];}// 初始化前缀和数组for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {prefixSum[i][j] = 0;}}// 计算第一行的前缀和for (int j = 1; j < cols; j++) {prefixSum[1][j] = matrix[1][j]+prefixSum[1][j-1];}// 计算第一列的前缀和for (int i = 2; i < rows; i++) {prefixSum[i][1] = prefixSum[i - 1][1] + matrix[i][1];}// 计算其他位置的前缀和for (int i = 2; i < rows; i++) {for (int j = 2; j < cols; j++) {prefixSum[i][j] = matrix[i][j] + prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1];}}return prefixSum;
}int main()
{int n,q;cin>>n>>q;int** origin=new int*[n+1];for(int i=0;i<n+1;i++){origin[i]=new int[n+1];fill(origin[i],origin[i]+n+1,0);}int** diff=computeDifferenceArray(origin,n+1,n+1);for(int i=1;i<=q;i++){int x1,y1,x2,y2;cin>>x1>>y1>>x2>>y2;updateDiffArray(diff,x1,y1,x2,y2,1,n+1,n+1);}int** ans=build2DPrefixSumArray(diff,n+1,n+1);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)cout<<ans[i][j]<<" ";cout<<endl;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1555586.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

余承东直播论道智能驾驶:激光雷达不可或缺,华为ADS 3.0引领安全创新

华为余承东:激光雷达,智能驾驶安全性的关键 9月29日,华为消费者业务集团CEO余承东在一场引人注目的直播中,与知名主持人马东就智能驾驶技术的最新进展进行了深入交流。在这场直播中,余承东针对激光雷达在智能驾驶中的必要性问题,发表了明确且深刻的观点,引发了业界和公众…

网关路由登录校验

网关过滤器 登录校验必须在请求转发到微服务之前做&#xff0c;否则就失去了意义。而网关的请求转发是Gateway内部代码实现的&#xff0c;要想在请求转发之前做登录校验&#xff0c;就必须了解Gateway内部工作的基本原理。 暂时无法在飞书文档外展示此内容 如图所示&#xff…

一、Python(介绍、环境搭建)

一、介绍 Python 是一种高级编程语言&#xff0c;具有简洁易读的语法、丰富的库和强大的功能。Python是解释型语言&#xff0c;运行代码必须依赖安装好的解释器。Python目前存在两个版本&#xff1a;Python2、Python3&#xff08;主流使用&#xff09; 二、环境搭建 1.安装P…

四、函数顶层变量

函数&顶层变量 函数定义创建和使用 顶层变量递归函数实用库函数高阶函数与lambda表达式函数类型变量类型别名匿名函数lambda表达式基本用法lambda的简写 内联函数 函数 定义 其实函数我们在一开始就在使用了&#xff1a; fun main() {println("Hello World") …

Python 语言学习——应用1.1 数字图像处理(第一节,颜色)

目录 1.基础知识 2.实战演示 1.基础知识&#xff1a; 1.图像的表示. 函数表示&#xff1a;图像是二维信号&#xff0c;定义为二维函数f(x,y)&#xff0c;其中&#xff0c;x、y是空间坐标&#xff0c;f(x,y)是点(x,y)的幅值。拓展看&#xff0c;视频&#xff0c;又称动态图像…

一阶差分模板的频率响应

一阶差分模板不同于二阶差分模板&#xff0c;它是一个奇对称的模板&#xff0c;傅里叶变换是纯虚数&#xff0c;无法用图形直接显示傅里叶变换&#xff0c;只能显示幅值谱。 冈萨雷斯的这个图我一直很好奇是怎么显示的&#xff0c;也没有坐标轴标出变量表示。 如今终于想明白…

论文笔记:微表情欺骗检测

整理了AAAI2018 Deception Detection in Videos 论文的阅读笔记 背景模型实验可视化 背景 欺骗在我们的日常生活中很常见。一些谎言是无害的&#xff0c;而另一些谎言可能会产生严重的后果。例如&#xff0c;在法庭上撒谎可能会影响司法公正&#xff0c;让有罪的被告逍遥法外。…

04-SpringBootWeb案例(中)

3. 员工管理 完成了部门管理的功能开发之后&#xff0c;我们进入到下一环节员工管理功能的开发。 基于以上原型&#xff0c;我们可以把员工管理功能分为&#xff1a; 分页查询&#xff08;今天完成&#xff09;带条件的分页查询&#xff08;今天完成&#xff09;删除员工&am…

服务器conda环境安装rpy2

参考博客 https://stackoverflow.com/questions/68936589/how-to-select-r-installation-when-using-rpy2-on-conda 现在我遇到这样一个问题&#xff0c;服务器系统环境没有R(没有权限安装&#xff09;&#xff0c;我只能在minconda的conda环境中使用R, 使用方法如下 我现在…

芝法酱学习笔记(0.6)——nexus与maven私库

一、私库的需求 在一个公司中&#xff0c;后端程序员通常几十上百个。在没有镜像私库的情况下&#xff0c;每当引入新库时&#xff0c;大家都会从maven中央仓库下载一遍这个库。这样无疑十分浪费。再加之国家的防火墙政策&#xff0c;许多人下载lib包可能还会十分缓慢。不同程…

Python水循环标准化对比算法实现

&#x1f3af;要点 算法区分不同水循环数据类型&#xff1a;地下水、河水、降水、气温和其他&#xff0c;并使用相应标准化降水指数、标准化地下水指数、标准化河流水位指数和标准化降水蒸散指数。绘制和计算特定的时间序列比较统计学相关性。使用相关矩阵可视化集水区和显示空…

推荐:五种限流(Rate Limiting)算法

推荐&#xff1a;五种限流(Rate Limiting)算法&#xff0c;发现一个不错的讲这个算法的UP,地址是&#xff1a;05~五种限流(Rate Limiting)算法_哔哩哔哩_bilibili https://www.bilibili.com/video/BV11k4SerE74/ 全部用动画展示&#xff0c;十分生动&#xff0c;比如漏桶算法&…

短剧小程序短剧APP在线追剧APP网剧推广分销微短剧小剧场小程序集师知识付费集师短剧小程序集师小剧场小程序集师在线追剧小程序源码

一、产品简介功能介绍 集师专属搭建您的独有短剧/追剧/小剧场小程序或APP平台 二、短剧软件私域运营解决方案 针对短剧类小程序的运营&#xff0c;以下提出10条具体的方案&#xff1a; 明确定位与目标用户&#xff1a; 对短剧类小程序进行明确定位&#xff0c;了解目标用户群体…

【AI知识点】置信区间(Confidence Interval)

置信区间&#xff08;Confidence Interval, CI&#xff09; 是统计学中用于估计总体参数的范围。它给出了一个区间&#xff0c;并且这个区间包含总体参数的概率等于某个指定的置信水平&#xff08;通常是 90%、95% 或 99%&#xff09;。与点估计不同&#xff0c;置信区间通过区…

开源的云平台有哪些?

开源云平台为用户提供了构建、管理和运行云基础设施及应用的能力&#xff0c;同时允许社区参与开发和改进。以下是一些知名的开源云平台&#xff1a; 1. OpenStack 简介&#xff1a;OpenStack&#xff1a;一个广泛使用的开源云平台&#xff0c;它由多个组件组成&#xff0c;提…

深度学习中的结构化概率模型 - 结构化概率模型的深度学习方法篇

序言 在深度学习的广阔领域中&#xff0c;结构化概率模型&#xff08; Structured Probabilistic Model \text{Structured Probabilistic Model} Structured Probabilistic Model&#xff09;扮演着至关重要的角色。这类模型利用图论中的图结构来表示概率分布中随机变量之间的…

精品WordPress主题/响应式个人博客主题Kratos

Kratos 是一款专注于用户阅读体验的响应式 WordPress 主题&#xff0c;整体布局简洁大方&#xff0c;针对资源加载进行了优化。 Kratos主题基于Bootstrap和Font Awesome的WordPress一个干净&#xff0c;简单且响应迅速的博客主题&#xff0c;Vtrois创建和维护&#xff0c; 主…

Markdown实用语法汇总

说明&#xff1a; 本来只展示本人常用的、markdown特有优势的一些语法。表格输入markdown的弱项&#xff0c;不作介绍&#xff0c;借助软件创建即可。引用图片、音频、视频等&#xff0c;虽然很方便&#xff0c;但是内容集成度不高&#xff0c;需要上传发布的时候很不方便&…

学习C语言(23)

整理今天的学习内容 1.文件的概念 使用文件是为了将数据永久化地保存 按照文件功能&#xff0c;在程序设计中一般把文件分成两类&#xff1a; 每个文件都有一个唯一的文字标识&#xff0c;文字标识常被称为文件名&#xff0c;文件名包含文件路径&#xff0c;文件名主干和文件…

Apollo9.0 Planning2.0决策规划算法代码详细解析 (4): PlanningComponent::Proc()

&#x1f31f; 面向自动驾驶规划算法工程师的专属指南 &#x1f31f; 欢迎来到《Apollo9.0 Planning2.0决策规划算法代码详细解析》专栏&#xff01;本专栏专为自动驾驶规划算法工程师量身打造&#xff0c;旨在通过深入剖析Apollo9.0开源自动驾驶软件栈中的Planning2.0模块&am…