0x00基础算法 -- 0x03 前缀和与差分

1、前缀和

  1. 对于一个给定的数组A,它的前缀和数列S是通过递推求得的:S[i] = \sum_{j = 1}^{i}A[j]
    //A[]和S[]的有效数据从下标1开始,方便后续计算
    s[0] = 0;
    for (int i = 1; i <= n; i++)
    {s[i] = s[i - 1] + A[i];
    }
  2. 作用:用于快速求得某一部分的和:对于一个部分和,即数列A某个下标区间内的数的和,可以表示为前缀和相减的形式:sum(l,r) = \sum_{i = l}^{r}A[i] = S[r] - S[l - 1]
     
  3. 在二维数组中,S[ i,j ]表示A数组的前缀和:S[ i ,j ] = \sum_{x = 1}^{i}\sum_{y=1}^{j}A[x,y],递推公式为:S[i,j] = S[i-1][j] + S[i,j-1] - S[i-1,j-1] + A[i,j]
    memset(S,0,sizeof(S));
    for (int i = 1; i <= n; i++)for(int j = 1; j <= n; j++){S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + A[i][j];}
  4. 作用:用于快速求得某一部分二维数组的和:对于二维数组的一部分和,即对于任意一个边长为R1,R2的矩阵的和,有:\sum_{i-R1+1}^{i}\sum_{j-R2+1}^{j}A[x,y] = S[i,j] - S[i-R1,j] - S[i,j-R2] + S[i-R,j-R]

1.1 题目--激光炸弹

99. 激光炸弹 - AcWing题库 

思路:

  1. 计算价值的前缀和
  2. 根据炸弹R*R的范围由前缀和计算
  3. 时间复杂度O(N^2)
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;const int N = 5010;
int n, r;
int sum[N][N];
PII max_xy = {1,1};
int res;int main()
{cin >> n >> r;//炸弹范围超过最大边界,直接计算5001以内的就行了 r = min(r, 5001);max_xy.first = max_xy.second = r;while(n--){int x,y,w;cin >> x >> y >> w;//加1是因为从{1,1}开始x +=  1, y += 1;sum[x][y] += w;if(x > max_xy.first)max_xy.first = x;if(y > max_xy.second)max_xy.second = y;}//前缀和for(int i = 1; i <= max_xy.first; i++)for(int j = 1; j <= max_xy.second; j++)sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];//求最大价值//每次枚举的都是r*r正方形的右下角,所以从r开始for (int i = r; i <= max_xy.first; i++)for(int j = r; j <= max_xy.second; j++)res = max(res, sum[i][j] - sum[i - r][j] - sum[i][j - r] + sum[i - r][j - r]); cout << res << endl;return 0;
}

 

2、差分

  1. 对于一个给定的数列A,它的差分数列B定义为:B[1] = A[1],B[i] = A[i] - A[i - 1](2 \leqslant i\leqslant n)
  2. 易发现前缀和和差分是一对互逆运算,差分数组的前缀和就是原数列A,前缀和序列S的差分数组的差分也是原序列A。
  3. 作用:给序列A的区间[ l,r ]所有数快速加上d,即:A_{l} + d,A_{l + 1} + d,A_{l + 2} + d,...,A_{r} + d = B[l] += d,B[r + 1] -= d
    通过差分数组的O(1)复杂度操作下,对差分数组求前缀和得到的序列就是序列A在指定[ l,r ]区域中所有数加上d。

2.1 题目--增减序列

100. 增减序列 - AcWing题库 

思路:

  1. 通过原序列a求出差分序列b,令b_{1} = a_{1},b_{n+1} = 0
  2. 目标是将原序列a所有数相等,等价于差分序列b中,b2、b3...bn全变为0(b1不需要为0,因为b1=a1)
  3. 每次对原序列a[ l,r ]区间内+1/-1,等价于在差分序列中,选择b_{l} + 1,b_{r + 1} - 1b_{l} - 1,b_{r + 1} + 1
  4. 从b1,b2,b3...bn中任选两个数的方法可分为4类:
    a、选bi和bj,其中2 <= i,j <= n,保证bi和bj一正一负的情况下,尽量多采取这个操作,可以快速将bi和bj接近0
    b、没有a的情况时,选b1和bj,其中 2 <= j <= n
    c、没有a的情况时,选bi和bn+1,其中 2 <= i <= n
    d、选b1和bn+1没有意义,会使原序列a全体+1/-1,浪费了一次操作
  5. 设b2、b3、b4...bn中正数总和为p,负数总和的绝对值为q。首先以正负数配对为主要方式,可以执行min(p,q)次;剩下的|p-q|次需要与b1或bn+1进行配对(即执行b或操作)。总的执行次数为:min(p,q) + |p - q| = max(p,q)次。
  6. 结果个数可以通过判断b1的不同值的个数来得出,b1的结果为|p-q| + 1,都是|p-q|次操作的结果,+1是存在结果b1没有进行配对;最终结果个数为|p-q| + 1
#include <iostream>
#include <algorithm>
using namespace std;const int N = 1e5 + 10;
int b[N];int main()
{int n;cin >> n;int cur;int per;cin >> cur;b[1] = cur,per = cur;long long p = 0, q = 0; //p表示正数之和,q表示负数绝对值之和for (int i = 2; i <= n; i++){cin >> cur;b[i] = cur - per;per = cur;if(b[i] >= 0)p += b[i];elseq -= b[i];} cout << max(p,q) << endl;cout << abs(p-q) + 1 << endl;return 0;
}

2.2 题目-- Tallest Cow

有N头牛站成一行。两头牛能够相互看见,当且仅当它们中间的牛身高都比它们矮。现在,我们只知道其中最高的牛是第P头,它的身高是H,不知道剩余N-1头牛的身高。但是,我们还知道M对关系,每对关系都指明了某两头牛Ai和Bi可以相互看见。求每头牛的身高最大可能是多少。
数据范围:1≤N,M≤10^4,1≤H≤10^6。

思路:初始化一个数组全为0表示牛的相对高度,假如有一对关系a和b位置的牛可以互相看到,那么就将a+1,a+2...b-2,b+1的位置全部减去1,就表示a和b之间的牛都比a和b之间的相对高度少1(为什么减1,为了保证每头牛高度最大)。第P头牛是最高的,所以b[p] = 0,所以最后得到的相对高度加上H就是绝对高度。

数组减1的操作可以使用差分来降低时间复杂度。
 

#include <iostream>
#include <map>
using namespace std;const int N = 10010;
map<pair<int,int>,bool> existed;
int c[N],d[N];int main()
{int n,p,h,m;cin >> n >> p >> h >> m;for(int i = 1; i <= m; i++){int a, b;cin >> a >> b;if(a > b) swap(a,b);if(existed[{a,b}]) continue;//可能会有一条关系重复输入的情况d[a+1]--,d[b]++;existed[{a,b}] = true;}//差分数组求前缀和得到目标序列for(int i = 1; i <= n; i++){c[i] = c[i - 1] + d[i];cout << c[i] + h << ' ';}cout << endl;return 0;
}

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

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

相关文章

四焦距聚焦型光场计算成像系统的设计

摘要: 光场相机是一种在图像传感器前增加微透镜阵列的新型相机结构&#xff0c;除了记录不同位置下光的强度及颜色外&#xff0c;也记录不同位置下光线的方向信息&#xff0c;从而能够计算目标场景的深度图和高阶相位图。该技术由于景深和分辨率相互制约&#xff0c;获得大景深…

ubuntu18.04 配置安卓编译环境

目前有个项目&#xff0c;验收时有个要求是在linux中进行编译打包生成apk文件。我平时都是在windows环境android studio中进行打包的&#xff0c;花了半天时间研究了一下&#xff0c;记录如下&#xff1a; 安装安卓sdk cd /opt wget https://dl.google.com/android/reposito…

qt QWidgetAction详解

1、概述 QWidgetAction是Qt框架中的一个类&#xff0c;它继承自QAction类。QWidgetAction允许开发者将自定义的小部件&#xff08;widget&#xff09;插入到基于QAction的容器中&#xff0c;如工具栏或菜单项中。这使得QWidgetAction成为创建复杂用户界面和自定义菜单项的强大…

工位管理革新:Spring Boot企业级系统

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理企业级工位管理系统的相关信息成为必然。开…

mysql查询语句(基础)

查询所需要的关键字 select 先在图形化工具导入数据库文件。 1&#xff1a;查询一个表中的所有列&#xff0c;使用通配符 * 。 select * from 表名 ; 2&#xff1a;查询表中的某列字段。 select 字段1,字段2,... from 表名; 字段之间使用逗号隔开。 …

Zookeeper的安装与使用

一、简介 1.1、概念 ZooKeeper 是一个开源的分布式协调服务&#xff0c;主要用于解决分布式系统中的数据一致性问题。它提供了一种可靠的机制来管理和协调分布式系统的各个节点。ZooKeeper 的设计目标是简化分布式应用的开发&#xff0c;提供简单易用的接口和高性能、高稳定性…

【论文阅读】医学SAM适配器:适应医学图像分割的任意分割模型

【论文阅读】医学SAM适配器&#xff1a;适应医学图像分割的任意分割模型 文章目录 【论文阅读】医学SAM适配器&#xff1a;适应医学图像分割的任意分割模型一、介绍二、联系工作三、方法四、实验 Medical SAM Adapter: Adapting Segment Anything Model for Medical Image Segm…

caozha-ip(IP地址查询源码)

caozha-ip&#xff0c;是基于原生PHP写的一套完整的IP转地址模块源码&#xff0c;支持自动获取IP&#xff0c;也支持查询指定IP&#xff0c;同时支持输出json、jsonp、text、xml、js等多种IP和地址格式&#xff0c;还可以细分为国家、省、市、地区&#xff0c;方便在各种系统里…

【Android、IOS、Flutter、鸿蒙、ReactNative 】文本Text显示

XML布局 参考 android:text <TextViewandroid:id"id/textview"android:layout_width"wrap_content"android:layout_height"wrap_content"android:text"Android Java TextView"app:layout_constraintBottom_toBottomOf"paren…

FPGA学习笔记#7 Vitis HLS 数组优化和函数优化

本笔记使用的Vitis HLS版本为2022.2&#xff0c;在windows11下运行&#xff0c;仿真part为xcku15p_CIV-ffva1156-2LV-e&#xff0c;主要根据教程&#xff1a;跟Xilinx SAE 学HLS系列视频讲座-高亚军进行学习 学习笔记&#xff1a;《FPGA学习笔记》索引 FPGA学习笔记#1 HLS简介及…

深入浅出JUC常用同步器

文章目录 1.JUC下同步器1.1 CountdownLatch 倒计数锁存器1.2 CyclicBarrier回环屏障1.3 Semephone 信号量 2.小结 1.JUC下同步器 日常开发会遇到主线程开启多个子线程去并行执行任务&#xff0c;并且主线程需要等待所有子线程执行完后在进行汇总的场景。 同步器出现之前&…

工位管理新策略:Spring Boot企业级应用

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

CAN总线物理层特性详细分析

目录 1. 简介 2. CAN总线拓扑图 3. CAN硬件电路 4. CAN电平标准 5. CAN收发器-TJA1050&#xff08;高速CAN&#xff09; 6. CAN物理层特性 1. 简介 CAN总线&#xff08;Controller Area Network Bus&#xff09;控制器局域网总线&#xff0c;是由BOSCH公司开发的一…

2024AAAI | DiffRAW: 利用扩散模型从手机RAW图生成单反相机质量的RGB图像

文章标题&#xff1a;《DiffRAW: Leveraging Diffusion Model to Generate DSLR-Comparable Perceptual Quality sRGB from Smartphone RAW Images》 原文链接&#xff1a;DiffRAW 本文是清华大学深圳研究院联合华为发表在AAAI-2024上的论文&#xff08;小声bb&#xff1a;华…

idea出现的问题

1.idea正常的运行,但是debug失败 原因&#xff1a;debug模式中使用的jdk和你在环境变量中配置的不是同一个jdk。或者说三处地方修改一致即可 1.File/Project Structure/Project Settings/Modules中的SDK 2.File/Project Structure/Platform Settings 中的SDKS 3.Run/Debug Conf…

uni-app之数据驱动的picker选择器( uni-data-picker)之可以选择到任意级别

背景说明 uni-app 官方的插件市场有数据驱动选择器&#xff0c;可以用作多级分类的场景。本人引入插件后&#xff0c;发现&#xff0c;在h5和微信小程序都只能选择到叶子级。而在给出的官方组件示例中确并非如此。 以选择年级&#xff0c;而不选择班级。然后&#xff0c;想试试…

vue3如何修改element ui input中type属性为textarea的高度

效果&#xff1a; 方法一&#xff1a;直接使用autosize <el-input:maxlength"500":autosize"{ minRows: 5, maxRows: 5 }"type"textarea"v-model"form.description"placeholder"请输入描述"></el-input> 方法二…

紫光展锐携手上赞随身Wi-Fi,让5G触手可及

近年来&#xff0c;随着各类移动应用层出不穷&#xff0c;人们对随时随地上网的需求日益增强&#xff0c;随身 Wi-Fi 设备以其便捷性、灵活性和相对较低的成本&#xff0c;成为用户满足办公、社交、娱乐等多元化需求的重要工具。5G技术的逐步普及为随身Wi-Fi市场注入了新的活力…

第四十三章 Vue之mapMutations简化mutations操作

目录 一、引言 二、完整代码 2.1. App.vue 2.2. main.js 2.3. Son1.vue 2.4. Son2.vue 2.5. index.js 一、引言 本章节我们通过掌握辅助函数mapMutations&#xff0c;来简化前面章节中调用mutations函数的繁琐方式。mapMutations 和 mapState很像&#xff0c;它是把位于…

C++编程语言:抽象机制:派生类(Bjarne Stroustrup)

第20章 派生类(Dirived Classes) 目录 20.1 引言 20.2 派生类 20.2.1 类成员函数 20.2.2 类构造函数和析构函数 20.3 派层次结构 20.3.1 类型域(Type Fields) 20.3.2 虚函数(Virtual Functions) 20.3.3 显式修饰(Explicit Qualification) 20.3.4 覆盖控制(O…