前缀和与差分大总结!!!C++

news2024/11/16 14:24:55

学了忘忘了学o(╥﹏╥)o

题源acwing

  • 讲解前缀和
    • 一维,用于序列
    • 二维,用于矩阵
  • 讲解差分
    • 什么是差分数组?
    • 一维差分数组
    • 二维差分数组
  • 题目一:前缀和
  • 题目二:子矩阵的和
  • 题目三:差分
  • 题目四:差分矩阵

讲解前缀和

什么时候用到前缀和呢?一般题目涉及到数组任意序列或者矩阵的话都有可能考点是前缀和。

一维,用于序列

具体做法:
首先做个预处理,定义一个sum[]数组,sum[i]代表a数组中前i个数的和。
求前缀和运算:

const int N = 1e5+10;
int sum[N], a[N]; //sum[i] = a[1] + a[2] + a[3] ..... a[i];
for(int i = 1; i <= n;i++)
{ 
    sum[i] = sum[i - 1] + a[i];   
}

如果想知道a1…an中任意一段的和,比如 a[l] 到a[r]

 scanf("%d%d", &l, &r);//l是起始,r是终点
 printf("%d\n", sum[r] - sum[l - 1]);//因为需要包括a[l]

二维,用于矩阵

矩阵的s[i, j]是表示以(1,1)为左上角节点,(i,j)为右下角节点的的矩阵和
在这里插入图片描述
求二维前缀和公式为:
s[i,j] = s[i - 1, j] + s[i, j - 1] - s[i - 1][j - 1] + a[i][j]
所以应用在代码上:

// 求 s[i, j]
for(int i = 1; i <= n; i++){
  for(int j = 1; j <=m; j++){
     s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
  }
}

如果想知道以(x1, y1)为左上角坐标,(x2, y2)为右下角坐标的句子

cout << s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]

讲解差分

什么是差分数组?

差分一听,啥jb玩意啊,其实就是前缀和倒过来,s是a的前缀和数组,a是s的差分数组

未来的小dream在这里插入图片描述
我本来打算这里简单写的,但是感觉我未来会有忘记的一天,痛定思痛写详细一点o(╥﹏╥)o谁赐我一个过目不忘的脑子

这块注意是,原数组a改动了之后,对应前缀和数组s的变化
假设a数组[3,1,2,5,7],对应s数组是[3,4,6,11,18]
将a[2]加3之后,对应s数组变成[3,4,6+3,11+3,18+3]
再将a[3]减3,对应s数组编程[3,4,6+3,11+3-3,18+3-3]
如下图
在这里插入图片描述
ok,未来的小dream,知道啥意思了吗
总结两点:
原数组单点操作,对应前缀和数组的区间操作
前缀和数组的区间操作,对应原数组的单点操作

这两点之间来回切换思考题目反应要快

次背景下可以有一种题型,题目对a进行多次区间操作,其变化后的a数组!
ok,怎么思考?

对s进行区间操作,之后求a数组,是不是更好求一点,但是题目是对a进行区间操作,怎么办?
可以构造出一个b数组,b数组的前缀和是a数组,现在对a数组进行区间操作,就是对b数组的前缀和数组进行操作,最后将变化后的前缀和数组对应到b上,在从b还原出数组a

简单的说:将对a的区间操作,转换为对b的两点操作,最后由b还原a
这里的b数组就是a的差分数组,

一维差分数组

忘了的再回忆一遍,a是b的前缀和,b是a的差分,a[i][j] = b[1][1] +…+b[i][j]
ok,继续

操作一:给区间[l, r]中的每个数加上c

b[l] += c,b[r + 1] -= c

操作二:知道a数组求b数组

b[i] = a[i] - a[i - 1]

二维差分数组

扩展到二维。s[][]是a[][]的前缀和数组,那么a[][]是s[][]的差分数组
假设已经构造好了a[][]。
操作:构建差分数组
相当于在全为0的二维数组加,所以加值都是一样的
现在来执行加的操作

a[x1][y1] += c;
a[x1][y2+1] -= c;
a[x2+1][y1] -= c;
a[x2+1][y2+1] += c

等价于:

for(int i = x1; i <= x2; i ++)
	for(int j = y1; j <= y2; j ++)
		s[i][j] += c;

其实也很好理解
在这里插入图片描述
将加法操作封装成一个函数

void insert(int x1,int y1,int x2,int y2,int c)
{     //对a数组执行插入操作
      //等价于对s数组中的(x1,y1)到(x2,y2)之间的元素都加上了c
    a[x1][y1]+=c;
    a[x2+1][y1]-=c;
    a[x1][y2+1]-=c;
    a[x2+1][y2+1]+=c;
}

题目一:前缀和

在这里插入图片描述
蛮简单属于前缀和入入入入入入门级题目,只涉及到了序列

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N];//保存原数组
int s[N];//保存前缀和数组
int main(){
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i ++){
        cin >> a[i];
    }
    //开始计算前缀和
    for(int i = 1; i <= n; i ++){
        s[i] = s[i - 1] + a[i];
    }
    
    while(m --){
        int l, r;
        cin >> l >> r;
        cout << s[r] - s[l - 1] << endl;
    }
}

其中需要注意的地方:
a数组也就是原数组,因为s[i]数组的含义是前i个字符和,为了和s[i]对应,a[0]应该初始化为0,当然s[0]也是0

题目二:子矩阵的和

在这里插入图片描述
也是前缀和矩阵的入门级题目了,我这次好好总结,以后再也不忘记了
┭┮﹏┭┮

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int a[N][N];
int s[N][N];
int main(){
    int n, m, q;
    cin >> n >> m >> q;
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            cin >> a[i][j];
        }
    }
    //计算前缀和s[i][j]
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
        }
    }
    while(q --){
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        cout << s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1] << endl;
    }
}

和第一题一样要注意,下标都从1开始

题目三:差分

在这里插入图片描述
首先构造差分数组,接着对应在差分数组上进行两点操作
最后将对应差分数组转化为序列输出
小dream,o(╥﹏╥)o劝你好好学习

很多题解会用a,b数组
我为了和前缀和形成对应还是用s和a数组

#include<iostream>
using namespace std;
const int N  = 1e5 + 10;
int a[N];
int s[N];
int main(){
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i ++){
        cin >> s[i];
        a[i] = s[i] - s[i - 1];
    }
    while(m --){
        int l, r, c;
        cin >> l >> r >> c;
        a[l] += c;
        a[r + 1] -= c;
    }
    for(int i = 1; i <= n; i ++){
        s[i] = s[i - 1] + a[i];
        cout << s[i] << " ";
    }
}

没有要注意的,小dream多细点心,然后segment fault有可能是因为你数组开的不够大

题目四:差分矩阵

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int s[N][N];
int a[N][N];
void insert(int x1, int y1, int x2, int y2, int c){
    a[x1][y1] += c;
    a[x1][y2 + 1] -= c;
    a[x2 + 1][y1] -= c;
    a[x2 + 1][y2 + 1] += c;
}
int main(){
    int n, m, q;
    cin >> n >> m >> q;
    //输入数组
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            cin >> s[i][j];
        }
    }
    //构建差分数组
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            insert(i, j, i, j, s[i][j]);
        }
    }
    //对a进行操作
    while(q --){
        int x1, y1, x2, y2, c;
        cin >> x1 >> y1 >> x2 >> y2 >> c;
        insert(x1, y1, x2, y2, c);
    }
    //由a推出s,即可得到答案
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
        }
    }
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            cout << s[i][j] << " ";
        }
        cout << endl;
    }
}

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

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

相关文章

案例分享-国外轻松感UI设计赏析

国外UI设计倾向于采用简洁的布局、清晰的排版和直观的交互方式&#xff0c;减少用户的认知负担&#xff0c;从而营造出轻松的使用体验。这种设计风格让用户能够快速找到所需信息&#xff0c;降低操作难度&#xff0c;提升整体满意度。 在注重美观的同时&#xff0c;更加重视用户…

便携移动工作站,端侧 AI 大模型设备折腾笔记:ROG 幻 X 和 4090 扩展坞

为了本地测试和开发更丝滑&#xff0c;最近入手了一套新设备 ROG 幻 X Z13 和 ROG XG Mobile 4090 扩展坞。 基于这套设备&#xff0c;我搭了一套 Windows x WSL2 x CUDA 的开发环境。分享一下折腾记录&#xff0c;或许对有类似需求的你也有帮助。 写在前面 最近因为各种事情…

【MySQL】索引 【下】{聚簇索引VS非聚簇索引/创建主键索引/全文索引的创建/索引创建原则}

文章目录 1.聚簇索引 VS 非聚簇索引经典问题 2.索引操作创建主键索引唯一索引的创建普通索引的创建全文索引的创建查询索引删除索引索引创建原则 1.聚簇索引 VS 非聚簇索引 之前介绍的将所有的数据都放在叶子节点的这种存储引擎对应的就是 InnoDB 默认存储表数据的存储结构。 …

【大模型系列】Video-LaVIT(2024.06)

Paper&#xff1a;https://arxiv.org/abs/2402.03161Github&#xff1a;https://video-lavit.github.io/Title&#xff1a;Video-LaVIT: Unified Video-Language Pre-training with Decoupled Visual-Motional TokenizationAuthor&#xff1a;Yang Jin&#xff0c; 北大&#x…

[Office] Word 特殊字符

0 打开“特殊字符集” 依次选择&#xff1a;Insert -> Symbol -> More Symbol 1 带圈编号 字体Font选择Wingdings

嵌入式Linux:符号链接(软链接)和硬链接

目录 1、符号链接&#xff08;软链接&#xff09; 2、硬链接 3、link()函数 4、symlink()函数 5、readlink()函数 在 Linux 系统中&#xff0c;符号链接&#xff08;软链接&#xff09;和硬链接是两种创建文件链接的方法。理解它们的区别和使用场景对于文件系统的管理非常…

错误:请查看是否设备未加入到证书列表或者确认证书类型是否匹配

这个问题实际上网上都有解法&#xff0c;但是可能没有那么的清楚&#xff0c;大家在各种问&#xff0c;我既然搞定了&#xff0c;就分享给大家吧网上解法&#xff1a; 开发调试需要另外创建开发证书和描述文件&#xff0c;描述文件同时绑定开发设备解读&#xff1a; 实际上这句…

举例详细学习和分析后端业务逻辑代码开发思路

在此之前&#xff0c;先来补充一下上一篇文章的一点内容&#xff1a;上一篇文章点击此处详看 对于画线的这句话&#xff0c;来详细解释一下吧&#xff01; 这里面说&#xff0c;对于service服务层&#xff0c;如果我们所需要实现的业务比较简单的话可以直接在...service接口里面…

Spring事件监听的核心机制及其原理

Spring事件监听 Spring的事件监听机制主要由三大核心部分组成即事件&#xff0c;监听器和播放器三部分组成。 事件的发布是通过spring当中的pulishEvent方法实现。事件监听实现是通过监听器监听了对应事件的监听器来实现的。 事件监听的作用&#xff1a;为系统业务之间进行一…

一种可以灵活、高速测试半导体测试中使用的老化板的系统

本文介绍了一种可以灵活、高速测试半导体测试中使用的老化板的系统。 定义&#xff1a;Burn-in Board Testing System是一种通过模拟极端使用条件&#xff08;如高温、高压、高湿等&#xff09;来加速半导体器件老化&#xff0c;并检测其潜在失效的测试系统。目的&#xff1a; …

如何使用 Puppeteer 绕过 Akamai

摘要&#xff1a; 本文深入探讨了在面对Akamai强大防护下的网页抓取挑战时&#xff0c;如何运用Puppeteer这一强大的Node.js库&#xff0c;通过模拟真实用户行为、动态请求处理等策略&#xff0c;高效且隐蔽地收集数据。我们将一步步揭开Puppeteer绕过Akamai的神秘面纱&#x…

红酒标签设计:艺术与品味的结合

在红酒的世界里&#xff0c;每一瓶酒都如同一位优雅的舞者&#xff0c;在酒柜的舞台上静静诉说着自己的故事。而红酒的标签&#xff0c;则是这位舞者身上较华丽的舞裙&#xff0c;它不仅是红酒的身份证明&#xff0c;更是艺术与品味的很好结合。今天&#xff0c;我们就来聊聊红…

计网 - 传统的类网络划分 vs 无类别域间路由CIDR

文章目录 A、B、C 类网络的基本概念和历史背景A 类网络B 类网络C 类网络实际应用场景 CIDR&#xff08;无类别域间路由&#xff09;基本概念CIDR 的表示方法计算 CIDR 网络段的步骤步骤 1&#xff1a;确定网络掩码步骤 2&#xff1a;计算网络地址步骤 3&#xff1a;计算广播地址…

二刷代码随想录训练营Day 11| 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素、总结

1.逆波兰表达式 题目链接/文章讲解/视频讲解&#xff1a;代码随想录 代码&#xff1a; class Solution { public:int evalRPN(vector<string>& tokens) {stack<long long> st;for(int i 0; i < tokens.size(); i){if(tokens[i] "" || tokens[i…

横看成岭侧成峰,山的叫法何其多。丘 陵 峰 岭 峦 岑 峭 嶂 岳 屺 岵 峡 岬 冈 崮 麓 顶 梁 包 坡 尖

文章目录 引言顶、梁、包、坡、尖山脚叫麓较低而平的山脊叫冈(岗)四周陡峭顶上较平的山叫崮(g)两山之间,有水为峡两山之间,无水为岬(jiǎ)没有草木的山叫屺(qǐ)多草木的山叫岵(h)高而险的山叫嶂高而大的山叫岳高而陡的山叫峭(qio)小而高的山叫岑小而尖的山叫峦高…

在亚马逊云科技AWS上开发大模型应用服务并设计提示词工程

项目简介&#xff1a; 接下来&#xff0c;小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 本次介绍的是如何利用亚…

昇思25天学习打卡营第6天|基础知识-函数式自动微分

目录 环境 函数与计算图 微分函数与梯度计算 Stop Gradient Auxiliary data 神经网络梯度计算 学习打卡时间 神经网络的训练主要使用反向传播算法&#xff0c;模型预测值&#xff08;logits&#xff09;与正确标签&#xff08;label&#xff09;送入损失函数&#xff08…

【C++红黑树应用】模拟实现STL中的map与set

目录 &#x1f680; 前言一&#xff1a; &#x1f525; 红黑树的修改二&#xff1a; &#x1f525; 红黑树的迭代器 三&#xff1a; &#x1f525; perator() 与 operator--() 四&#xff1a; &#x1f525; 红黑树相关接口的改造✨ 4.1 Find 函数的改造✨ 4.2 Insert 函数的改…

推荐珍藏已久的 3 款优质电脑软件,每一款都值得拥有

Advanced Find and Replace Advanced Find and Replace是一款功能强大的文本查找和替换工具&#xff0c;能够高效地在多个文档中进行复杂的内容操作。它支持通配符和正则表达式&#xff0c;使得用户可以精确地定位和替换特定的文本内容。该软件不仅适用于普通文本文件&#xff…

防洪评价报告编制方法与水流数学模型建模技术

原文链接&#xff1a;防洪评价报告编制方法与水流数学模型建模技术https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247610610&idx2&sn432d30cb40ec36160d635603c7f22c96&chksmfa827115cdf5f803ddcaa03a21e3721d6949d6a336062bb38170e3f9d5bd4d391cc36cc…