前缀和与差分

文章目录

  • 前缀和
    • 一维前缀和
      • 公式
      • CODE
    • 二维前缀和
      • 公式
      • CODE
  • 差分
    • 一维差分
      • 思路
      • 作用
      • CODE
    • 二维差分
      • 思路
      • CODE



前缀和

一维前缀和

板子题:https://www.acwing.com/activity/content/problem/content/829/

公式

S [ i ] = a [ i ] + S [ i − 1 ] S[i] = a[i] + S[i - 1] S[i]=a[i]+S[i1]

CODE

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10;
int n, m, l, r;
int a[N], s[N];

int main()
{
    cin >> n >> m;
    
    for(int i = 1; i <= n; ++i){
        scanf("%d", &a[i]);
        s[i] = s[i - 1] + a[i];
    }
    
    while(m--){
        cin >> l >> r;
        printf("%d\n", s[r] - s[l - 1]);
    }
}

二维前缀和

板子题:https://www.acwing.com/activity/content/problem/content/830/

公式

S [ i ] [ j ] = S [ i − 1 ] [ j ] + S [ i ] [ j − 1 ] − S [ i − 1 ] [ j − 1 ] + a [ i ] [ j ] S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + a[i][j] S[i][j]=S[i1][j]+S[i][j1]S[i1][j1]+a[i][j]

CODE

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;
int n, m, q;
int x1, x2, y1, y2;
int a[N][N], s[N][N];

int main()
{
    cin >> n >> m >> q;
    
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j){
            scanf("%d", &a[i][j]);
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
        }
        
    while (q -- ){
        cin >> x1 >> y1 >> x2 >> y2;
        printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);
        
    }
}

差分

一维差分

板子题:https://www.acwing.com/activity/content/problem/content/831/

思路

差分其实是前缀和的逆运算,我们假想有一个数组b[],它的前缀和是数组a[],也就是说:
b [ i ] = a [ i ] − a [ i − 1 ] b[i] = a[i] - a[i - 1] b[i]=a[i]a[i1]

作用

这个b[]数组有什么用呢?
在我们对a[]的元素进行加减操作时,如果采用遍历a[]的方法,时间是 o ( N ) o(N) o(N) 的,但是如果我们用b[]对其优化可以使时间复杂度降到 o ( 1 ) o(1) o(1)

a[] [ i , j ] [i, j] [i,j] 段进行+k操作,我们可以在 b[i] + k并在b[j + 1] - k。当我们对b[]求前缀和时,从i开始的每个元素都会+k,但是我们只要加到a[j]就结束了,所以在a[j + 1]进行归位。

CODE

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10;
int n, m;
int l, r, c;
int a[N], b[N];

void insert(int l, int r, int c){
    b[l] += c;
    b[r + 1] -= c;
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; ++i){ 
        scanf("%d", &a[i]);
        insert(i, i, a[i]);
    }
    
    while (m -- ){
        cin >> l >> r >> c;
        insert(l, r, c);
    }
    
    for(int i = 1; i <= n; ++i) printf("%d ", b[i] += b[i - 1]);
}

整个差分数组的精髓就在于insert()函数,非常巧妙啊,尤其是在读入阶段对b[]数组进行初始化时的操作,这个操作的意义如下:

解释
来源:https://www.acwing.com/activity/content/code/content/39799/


二维差分

板子题:https://www.acwing.com/activity/content/problem/content/832/

思路

答题思路跟一维差分差不多,借鉴二维前缀和的操作我们可以得到以下公式:
a [ i ] [ j ] = b [ i ] [ j ] − b [ i − 1 ] [ j ] − b [ i ] [ j − 1 ] + b [ i − 1 ] [ j − 1 ] a[i][j] = b[i][j] - b[i - 1][j] - b[i][j - 1] + b[i - 1][j - 1] a[i][j]=b[i][j]b[i1][j]b[i][j1]+b[i1][j1]

那我们插入函数该怎么写呢?
一样的原理:
b [ x 1 ] [ y 1 ] + = c b [ x 2 + 1 ] [ y 1 ] − = c b [ x 1 ] [ y 2 + 1 ] − = c b [ x 2 + 1 ] [ y 2 + 1 ] + = c b[x1][y1] += c\\ b[x2 + 1][y1] -= c\\ b[x1][y2 + 1] -=c\\ b[x2 + 1][y2 + 1] += c b[x1][y1]+=cb[x2+1][y1]=cb[x1][y2+1]=cb[x2+1][y2+1]+=c

CODE

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int n, m, q;
const int N = 1010;
int a[N][N], b[N][N];
int x1, y1, x2, y2, c;

void insert(int x1, int y1, int x2, int y2, int c){
    b[x1][y1] += c;
    b[x2 + 1][y1] -= c;
    b[x1][y2 + 1] -= c;
    b[x2 + 1][y2 + 1] += c;
}

int main()
{
    cin >> n >> m >> q;
    
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j){
            scanf("%d", &a[i][j]);
            insert(i, j, i, j, a[i][j]);
        }
        
    while(q--){
        cin >> x1 >> y1 >> x2 >> y2 >> c;
        insert(x1, y1, x2, y2, c);
    }
    
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= m; ++j){
            printf("%d ", b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1]);
        }
        printf("\n");   
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据Doris(三十):删除数据(Delete)

文章目录 删除数据(Delete) 一、​​​​​​​DELETE FROM Statement(条件删除)

【Cmake】Cmake基础学习

CMake学习 一、基础学习 1. 利用Cmake进行单个源代码构建可执行文件 (1)基础命令 最基本的 CMake项目是由单个源代码文件构建的可执行文件。对于这样的简单项目,只需要一个包含三个命令的 CMakeLists.txt 文件。 注意: 虽然 CMake 支持大写、小写和混合大小写命令,但是…

矩阵置零[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个m x n的矩阵&#xff0c;如果一个元素为0&#xff0c;则将其所在行和列的所有元素都设为0。请使用原地算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[…

[C++]六大默认成员函数详解

☃️个人主页&#xff1a;fighting小泽 &#x1f338;作者简介&#xff1a;目前正在学习C和Linux &#x1f33c;博客专栏&#xff1a;C入门 &#x1f3f5;️欢迎关注&#xff1a;评论&#x1f44a;&#x1f3fb;点赞&#x1f44d;&#x1f3fb;留言&#x1f4aa;&#x1f3fb; …

【VUE】There are multiple modules with names that only differ in casing.

报错 There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these module identifiers: 图示原因&#xff1a;大小写&#xff0c;有…

C#——多线程之异步调用容易出现的问题

C#——多线程之异步调用容易出现的问题 Q1&#xff1a;For中异步调用函数且函数输入具有实时性 Q1&#xff1a;For中异步调用函数且函数输入具有实时性 在项目进行过程中&#xff0c;发现For中用异步调用带有输入参数的函数时&#xff0c;会由于闭包特性&#xff0c;以及Task.…

ELK----日志分析

ELK相关知识 ELK的概念与组件 ELK平台是一套完整的日志集中处理解决方案&#xff0c;将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用&#xff0c; 完成更强大的用户对日志的查询、排序、统计需求。 E&#xff1a;ElasticSearch &#xff08;ES&#xff09; ES是…

C#,《小白学程序》第二十一课:大数的减法(BigInteger Subtract)

1 文本格式 using System; using System.Linq; using System.Text; using System.Collections.Generic; /// <summary> /// 大数的&#xff08;加减乘除&#xff09;四则运算、阶乘运算 /// 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法 /// </summary> p…

C/C++ 常用加密与解密算法

计算机安全和数据隐私是现代应用程序设计中至关重要的方面。为了确保数据的机密性和完整性&#xff0c;常常需要使用加密和解密算法。C是一种广泛使用的编程语言&#xff0c;提供了许多加密和解密算法的实现。本文将介绍一些在C中常用的加密与解密算法&#xff0c;这其中包括Xo…

力扣373场周赛题解

第一题&#xff1a; 这个题是一个简单题&#xff0c;数据范围也特别小&#xff0c;所以直接使用模拟方式暴力解答。 直接进行行移动的过程&#xff0c;然后检查移动后的结果是否与移动前相同。 代码&#xff1a; ​ public class Solution {// 将指定行循环右移k次pri…

OpenCV完结篇——计算机视觉(人脸识别 || 车牌识别)

文章目录 Haar人脸识别方法Haar识别眼鼻口HaarTesseract进行车牌识别深度学习基础知识dnn实现图像分类 Haar人脸识别方法 scaleFactor调整哈尔级联器的人脸选框使其能框住人脸 官方教程指路 每个特征都是通过从黑色矩形下的像素总和减去白色矩形下的像素总和获得的单个值 级…

排序篇(六)----排序小结(不用三连,混流量券)

排序篇(六)----排序小结 排序算法复杂度及稳定性分析 直接插入排序的算法复杂度&#xff1a; 最好情况下&#xff0c;当数组已经有序时&#xff0c;直接插入排序的时间复杂度为O(n)&#xff0c;其中n是数组的大小。最坏情况下&#xff0c;当数组逆序排列时&#xff0c;直接插…

解析实人认证API的工作原理与应用场景

引言 随着数字化时代的不断发展&#xff0c;实人认证技术在各个领域中发挥着越来越重要的作用。其中&#xff0c;实人认证API作为一种先进的技术手段&#xff0c;通过输入姓名、身份证号码和一张人脸照片&#xff0c;与公安库身份证头像进行权威比对&#xff0c;从而返回比对分…

生物神经系统的基本原理 神经元Neuron

生物神经系统的基本原理涉及一系列复杂的生物学和生理学机制&#xff0c;主要可以分为以下几个方面&#xff1a; 神经元与突触&#xff1a;神经系统的基本单位是神经元&#xff0c;它们通过突触连接彼此。神经元接收并处理来自身体其他部分或环境的信息&#xff0c;然后通过电信…

FFmpeg零基础学习(二)——视频文件信息获取

目录 前言正文一、获取宽高信息1、核心代码2、AVFormatContext3、avformat_alloc_context4、avformat_open_input5、avformat_find_stream_info6、av_dump_format7、av_find_best_stream End、遇到的问题1、Qt Debug模式avformat_alloc_context 无法分配对象&#xff0c;而Rele…

【SQL Server Management】使用手册

目录 ⛳️【SQL Server Management】 ⛳️1. 启动登录 ⛳️2. 忘记密码 ⛳️3. 操作数据库和表 3.1 新建数据库text 3.2 新建表 3.3 编辑表 3.4 编写脚本 ⛳️【SQL Server Management】 ⛳️1. 启动登录 需要开启服务 ⛳️2. 忘记密码 登录windows--> 安全性 -->…

VMware虚拟机安装华为OpenEuler欧拉系统

首先去欧拉官方网站下载openEuler的安装镜像&#xff1a; openEuler下载 | 欧拉系统ISO镜像 | openEuler社区官网 我下载的是最新的23.03长期维护版本&#xff0c;架构选择x86_64。 创建新虚拟机&#xff1a;选择典型配置&#xff0c;点击下一步&#xff1a;选择下载的镜像文…

如何在手机上打开电脑端本地的网页

目录 一.手机端预览VSCode生成的网页站点二.手机端预览VS2022生成的 WebApi网页站点三.总结 今天遇到了2个小问题&#xff1a;1.想在手机上运行VSCode上写好的网页代码。2.同样在手机上运行VS2022 WebApi生成的网页。查找了一晚上资料&#xff0c;终于动手解决了&#xff0c;记…

虽不想承认,但这就是CSGO游戏搬砖行业的现状

其实整个搬砖市场&#xff0c;现在已经变得乌烟瘴气&#xff0c;散发着“恶臭”。童话个人非常鄙视那些虚有其表&#xff0c;大小通吃的做法&#xff0c;那些甚至连搬砖数据都看不懂的人&#xff0c;也出来吹嘘着“实力强大&#xff0c;经验丰富”。这个世界太浮躁了&#xff0…

ShowWeb-浏览器插件:可视化元素路径查看器

ShowWeb&#x1f47b;&#xff1a;可视化元素路径查看器适配【谷歌】【Edge】 每次写前端最烦的就是一层一层找元素&#xff0c;又臭又长。所以我开发了一个小插件来缓解这个问题&#xff0c;这个插件可以输出整个路径&#xff0c;并把最后元素的内容输出方便查看&#xff0c;…