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

前缀和算法习题篇(上)

在这里插入图片描述

1.一维前缀和

题目描述:

在这里插入图片描述

解法一:暴力解法:模拟

时间复杂度是O(n*q),会超时。

解法二:前缀和解法:快速求出数组中某一个连续区间的和

快速是指O(1),前缀和思想可把时间复杂度可降到O(q)。

算法思路:
  1. 先预处理出来一个前缀和数组:O(n)
  • dp[i] 表示: [1, i] 区间内所有元素的和,那么 dp[i - 1] 里面存的就是 [1, i - 1] 区间内所有元素的和。
  • 递推公式: dp[i] = dp[i - 1] + arr[i] ;
  1. 使用前缀和数组,快速求出某一个区间内所有元素的和:O(q)
  • 当询问的区间是 [l, r] 时:区间内所有元素的和为: dp[r] - dp[l - 1] 。

时间复杂度为O(q)+O(n).

为什么我们的下标要从1开始计数呢?

举例:当访问的区间是[0,2]时,区间内所有元素的和为dp[2]-dp[-1],这里的dp[-1]越界。而当访问的区间是[1,2]时,区间内所有元素的和为dp[2]-dp[0],使dp[0]=0即可,不会越界。

  • 为了处理边界情况
  • 初始化:添加虚拟结点(辅助结点)
代码实现:
#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);//防止溢出
   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;
}

2.二维前缀和

题目描述:

在这里插入图片描述
在这里插入图片描述

解法一:暴力解法:模拟

时间复杂度是O(n* m *q),会超时。

解法二:前缀和解法

算法思路:

1.预处理出来一个前缀和矩阵: O(m*n)

  • dp[i][j]表示:从[1,1]位置到[i,j]位置,这段区间里面所有元素的和。

在这里插入图片描述

2.使用前缀和矩阵: O(q)
在这里插入图片描述

时间复杂度为O(m*n)+O(q).

代码实现:
#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/397967.html

相关文章:

  • C:原反补码
  • 群控系统服务端开发模式-应用开发-前端图片格式功能开发
  • 树状数组+概率论,ABC380G - Another Shuffle Window
  • 丹摩征文活动 |【前端开发】HTML+CSS+JavaScript前端三剑客的基础知识体系了解
  • 【数据库取证】快速从服务器镜像文件中获取后台隐藏数据
  • Tensorflow基本概念
  • 【点云上采样】最近邻插值上采样算法 增加点云密度
  • C++ 编程基础(5)类与对象 | 5.8、面向对象五大原则
  • vue3中将在线url地址转为图片显示方法教程
  • RabbitMQ 通道(Channel)详解:方法使用、消息确认与拒绝
  • 零基础怎么开始学网络安全(非常详细)零基础入门到精通
  • Mac Java 使用 tesseract 进行 ORC 识别
  • [Qt] Qt删除文本文件中的某一行
  • springboot基于Web足球青训俱乐部管理后台系统开发(代码+数据库+LW)
  • 【SpringBoot】23 文件预览(kkFileView)
  • 前端传数组 数据库存Json : [1,2,3]格式
  • Bugku CTF_Web——文件上传
  • 19.UE5道具掉落
  • 【功耗现象】com.gorgeous.lite后台Camera 使用2小时平均电流200mA耗电量400mAh现象
  • 想租用显卡训练自己的网络?AutoDL保姆级使用教程(PyCharm版)
  • redis序列化数据查询
  • 解决Windows远程桌面 “为安全考虑,已锁定该用户账户,原因是登录尝试或密码更改尝试过多。请稍后片刻再重试,或与系统管理员或技术支持联系“问题
  • 从零开始学习 sg200x 多核开发之 eth0 dhcpc 配置
  • 现代密码学|古典密码学例题讲解|AES数学基础(GF(2^8)有限域上的运算问题)| AES加密算法
  • python机器人Agent编程——多Agent框架的底层逻辑(上)
  • ISP网络服务商有哪些