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

前缀和--一维和二维模板

前缀和

在这里插入图片描述

【模板】前缀和

描述

给定一个长度为n的数组a1,a2,…ana1,a2,…a**n.

接下来有q次查询, 每次查询有两个参数l, r.

对于每个询问, 请输出al+al+1+…+ara**l+a**l+1+…+a**r

输入描述:

第一行包含两个整数n和q.

第二行包含n个整数, 表示a1,a2,…ana1,a2,…a**n.

接下来q行,每行包含两个整数 l和r.

1≤n,q≤1051≤n,q≤105
−109≤a[i]≤109−109≤a[i]≤109
1≤l≤r≤n1≤lrn

输出描述:

输出q行,每行代表一次查询的结果.

示例1

输入:

3 2
1 2 4
1 2
2 3

输出:

3
6

题目解析:
在这里插入图片描述

在这里插入图片描述

解法(前缀和):

算法思路:

a. 先预处理出来⼀个「前缀和」数组:

⽤ dp[i] 表⽰: [1, i] 区间内所有元素的和,那么 dp[i - 1] ⾥⾯存的就是 [1, i - 1] 区间内所有元素的和,那么:可得递推公式: dp[i] = dp[i - 1] + arr[i] ;

b. 使⽤前缀和数组,「快速」求出「某⼀个区间内」所有元素的和:

当询问的区间是 [l, r] 时:区间内所有元素的和为: dp[r] - dp[l - 1] 。

代码如下:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    //1.读入数据
    int n,q;
    cin>>n>>q;
    vector<int> arr(n+1);
    for(int i=1;i<=n;i++) cin>>arr[i];
    //2.预处理来一个前缀和数组
    vector<long long> dp(n+1);//用long long是为了防止溢出
    for(int i=1;i<=n;i++) dp[i]=dp[i-1]+arr[i];
    //3.使用前缀和数组
    int l=0,r=0;
    while(q--)
    {
        cin>>l>>r;
        cout<<dp[r]-dp[l-1]<<endl;
    }
    return 0;
}

【模板】二维前缀和

描述

给你一个 n 行 m 列的矩阵 A ,下标从1开始。

接下来有 q 次查询,每次查询输入 4 个参数 x1 , y1 , x2 , y2

请输出以 (x1, y1) 为左上角 , (x2,y2) 为右下角的子矩阵的和,

输入描述:

第一行包含三个整数n,m,q.

接下来n行,每行m个整数,代表矩阵的元素

接下来q行,每行4个整数x1, y1, x2, y2,分别代表这次查询的参数

1≤n,m≤10001≤n,m≤1000
1≤q≤1051≤q≤105
−109≤a[i][j]≤109−109≤a[i][j]≤109
1≤x1≤x2≤n1≤x1​≤x2​≤n
1≤y1≤y2≤m1≤y1​≤y2​≤m

输出描述:

输出q行,每行表示查询结果。

示例1

输入:

3 4 3
1 2 3 4
3 2 1 0
1 5 7 8
1 1 2 2
1 1 3 3
1 2 3 4

输出:

8
25
32

在这里插入图片描述

在这里插入图片描述

代码如下:

#include <iostream>
#include <vector>
using namespace std;

int main() 
{
    //1.读取数据
    int n=0,m=0,q=0;
    cin>>n>>m>>q;
    vector<vector<int>> arr(n+1,vector<int>(m+1));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        cin>>arr[i][j];
    //2预处理前缀和矩阵
    vector<vector<long long>> dp(n+1,vector<long long>(m+1));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        dp[i][j]=dp[i-1][j]+dp[i][j-1]+arr[i][j]-dp[i-1][j-1];
    //3.使用前缀和矩阵
    int x1=0,y1=0,x2=0,y2=0;
    while(q--)
    {
        cin>>x1>>y1>>x2>>y2;
        cout<<dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1]<<endl;
    }
    return 0;
}

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

相关文章:

  • 一体式IO模块:打印机加工产线国产化降本增效的新利器
  • springboot中使用gdal将表中的空间数据转shapefile文件
  • GraalVM完全指南:云原生时代下使用GraalVM将Spring Boot 3应用转换为高效Linux可执行文件
  • 软件设计与体系结构
  • K8s HPA的常用功能介绍
  • 【从零开始入门unity游戏开发之——C#篇21】C#面向对象的封装——`this`扩展方法、运算符重载、内部类、`partial` 定义分部类
  • 【MySQL】索引的机制、使用
  • 机器学习—特性缩放
  • 执行 start.sh 脚本时打开一个单独的运行窗口
  • pdf内容三张以上转图片,使用spire.pdf.free
  • 【选择C++游戏开发技术】
  • 自动驾驶TPM技术杂谈 ———— 惯性导航定位技术
  • 速盾:高防 cdn 提供 cc 防护?
  • 双回路防静电监控仪安全保护生产全流程
  • Linux基础项目开发day2:量产工具——输入系统
  • 【存储设备专栏 2.6 -- linux 启动盘制作详细介绍】
  • Vert.x,Web - Restful API
  • 记EDU某人社局的漏洞挖掘复盘
  • 四种隔离级别是如何逐步加强事务隔离的,以及在底层如何使用锁机制和多版本控制(MVCC)来实现
  • HCIP--1
  • 新媒体优势
  • Spring Boot驱动的在线考试系统:JavaWeb技术实战
  • Scala入门基础(12)抽象类
  • 梯度下降算法优化—随机梯度下降、小批次、动量、Adagrad等方法pytorch实现
  • pico+Unity交互开发教程——手指触控交互(Poke Interaction)
  • 如何利用OpenCV和yolo实现人脸检测