每日一句:真正让人变好的选择过程都不会很舒服,所以人们明知道什么都不做,会比较轻松,但依旧选择追逐梦想。

前缀和

  • 前言
  • 一、一维前缀和
    • 1.前缀和是什么?
    • 2.暴力做法
    • 3.前缀和求区间大小
      • 3.1如何构成前缀和的形式?
    • 4.完整代码
  • 二、二维前缀和
    • 1.基本思路
    • 2.完整代码

前言

原数组: a[1], a[2], a[3], a[4], a[5], …, a[n]
前缀和: S[i] = a[1] +a[2] + a[3] + … + a[i]
前缀和能够快速的求出某一区间的和。

详细看下面的介绍。

一、一维前缀和

1.前缀和是什么?

用一个简单的列子去介绍

原数组: a[1], a[2], a[3], a[4], a[5], …, a[n]
前缀和: s[i] = a[1] + a[2] + a[3] + … + a[i]
前缀和就是用一个数组s去存数组a的前n项的和。
s[0] = 0
s[1] = a[1]
s[2] = a[1] + a[2]
s[n] = a[i] + a[2] + a[3] + …+a[n]
这样s[n]对应的就是a[1]—a[n]的和,s的每一项都这样对应,就构成了前缀和。
注:前缀和的下标一定要从1开始。

2.暴力做法

int n, m;cin >> n >> m;int sum = 0;for (int i = 1; i <= n; i++){cin >> a[i];}while (m--){int l, r;cin >> l >> r;sum = 0;for (int i = l; i <= r; i++){sum += a[i];}cout << sum << endl;}

这个就是用暴力的方法去做,也能求出区间[L,R]的和,但他的时间复杂度为O(n)那么当数据过于庞大的时候就会造成超时的情况。

暴力会超时。

3.前缀和求区间大小

如何利用前缀和去求区间大小呢?
有一个公式:s[r] - s[l - 1]。
就是这个公式,他的时间复杂度O(1),这就要比暴力的做法快上很多了。

3.1如何构成前缀和的形式?

 for (int i = 1; i <= n; i++){s[i] = s[i - 1] + a[i];}

s[1] = s[0] + a[1];
s[2] = s[1] + a[2];
s[3] = s[2] + a[3];
s[n] = s[n - 1] + a[n]
去遍历a数组,把当前a[n]的数加上s[n-1]的数,就能得到s[n],这个s[n]就是a[1,n]的和。

4.完整代码

#include <iostream>using namespace std;const int N = 1e6 + 10;int a[N],s[N];
//int main()//暴力做法
//{//  int n, m;
//  cin >> n >> m;
//  int sum = 0;
//  for (int i = 1; i <= n; i++)
//  {//      cin >> a[i];
//  }
//  while (m--)
//  {//      int l, r;
//      cin >> l >> r;
//      sum = 0;
//      for (int i = l; i <= r; i++)
//      {//          sum += a[i];
//      }
//      cout << sum << endl;
//  }
//  return 0;
//}
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;}return 0;
}

例题acwing795.前缀和

二、二维前缀和

1.基本思路

二维前缀和是建立在一维前缀和的基础上实现的,唯一不同的就是,这个是二维的。

s[1][1] = s[0][1] + s[1][0] - s[0][0] + a[1][1];
s[2][2] = s[1][2] + s[2][1] - s[1][1] + a[2][2];
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
注:下标从1开始
这样理解可能有点困难,画个图就知道了。

标红的区域代表的就是区间[i-1,j-1]的的和

标绿的区域就是区间[i-1,j]的和

标蓝的区域就是区间[i,j-1]的和

这个整体代表的就是区间[i,j]的和

由此可以看出,在计算s[i,j]的和的时候,是不是把区间s[i-1,j-1]多算了一次,所以应该把s[i-1,j-1]减去一次,就能得到区间s[i,j]正确的区间和了。

2.完整代码

#include <iostream>using namespace std;const int N = 1e3 + 10;int a[N][N], 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];}}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, x2, y1, y2;cin >> x1 >> y1 >> x2 >> y2;cout << s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1] << endl;}return 0;
}

例题acwing796.子矩阵的和


以上就是对前缀和的介绍,希望对大家有帮助。

前缀和(C++)实现相关推荐

  1. Redis 笔记(13)— scan 和 keys 寻找特定前缀key 字段(命令格式、使用示例、定位大key)

    1. keys Redis 提供了一个简单暴力的指令 keys 用来列出所有满足特定正则字符串规则的 key. 127.0.0.1:6379> keys * (empty array) 127. ...

  2. OpenCV 笔记(04)— OpenCV2 升级到 OpenCV3/CV4 的改动(去掉 CV_前缀、使用新的前缀替换、使用新的命名空间宏)

    1. 由于宏名称的变更照成的"未声明的标识符"系列问题 有时候,遇到此类问题加入一句 #include <cv.h> 便可以让 OpenCV3 或者 OpenCV4 也 ...

  3. Go 学习笔记(59)— Go 第三方库之 etcd/clientv3 封装为方法使用(建立连接、设置key-value、获取key-value、获取带前缀的key-value)

    1. 示例 1 package main import ("context""fmt""go.etcd.io/etcd/clientv3"& ...

  4. LeetCode简单题之检查字符串是否为数组前缀

    题目 给你一个字符串 s 和一个字符串数组 words ,请你判断 s 是否为 words 的 前缀字符串 . 字符串 s 要成为 words 的 前缀字符串 ,需要满足:s 可以由 words 中的 ...

  5. LeetCode简单题之检查单词是否为句中其他单词的前缀

    题目 给你一个字符串 sentence 作为句子并指定检索词为 searchWord ,其中句子由若干用 单个空格 分隔的单词组成. 请你检查检索词 searchWord 是否为句子 sentence ...

  6. CSS3无前缀脚本prefixfree.js与Animatable使用介绍

    要求 必备知识 本文要求基本了解 JAVASCRIPT 和 和 CSS3 基本知识. 运行环境 桌面端:IE9 +,Opera 10+,火狐3.5 +,Safari 4+和Chrome浏览器;移动端: ...

  7. kmp求前缀和后缀的最大重复部分

    hdu 2594 kmp水题 求s1的前缀和s2的后缀重复度的最大值 2013-06-05 11:16 1199人阅读 评论(0) 收藏 举报  分类: KMP(8)  版权声明:本文为博主原创文章, ...

  8. usaco ★Longest Prefix 最长前缀

    ★Longest Prefix 最长前缀 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列 28 分解成较短的(称之为元素的)序列很感兴趣. 如果一个集合 P 中 ...

  9. 洛谷 P2468 粟粟的书架 二分(主席树+前缀和)

    传送~:https://www.luogu.org/problem/P2468 看了一下数据也发现是两道题,后边当他是一个序列(n==1)的时候直接主席树二分区间前k大和就行了 但是有一个细节我觉得就 ...

  10. Monitor CodeForces - 846D ——二维前缀和

    Recently Luba bought a monitor. Mon itor is a rectangular matrix of size n × m. But then she started ...

最新文章

  1. android:listView Button 焦点问题
  2. android this context,Android應用開發中關於this.context=context的理解
  3. 2019 IROS—终生机器视觉数据集全球挑战赛
  4. 前端学习(3033):vue+element今日头条管理-反馈
  5. 移动端隐藏滚动条(最全面)
  6. C#LeetCode刷题之#453-最小移动次数使数组元素相等(Minimum Moves to Equal Array Elements)
  7. Yandex.Algorithm 2011 Round 2 D. Powerful array 莫队算法
  8. 一文读懂 Java 工程师学习路线!
  9. matlab中全局变量的作用域,在simulink中使用全局变量的方法
  10. mysql dcn_Tdsql DCN同步技术原理介绍
  11. 北京清大美博节能技术研究院励志人生格言
  12. 华为路由交换课程笔记10-GARP和GVRP
  13. 【C语言管理系统】 医院住院病人信息管理系统
  14. PASCAL VOC2012 数据集讲解与制作自己的数据集
  15. 第十二届蓝桥杯 Java 省赛 B 组部分真题解析
  16. vue2.0构建淘票票webapp
  17. 个人作品设计展示官网源码
  18. MYSQL 安装/ Navicat可视化数据库使用
  19. 计算机音乐单恋一枝花,单恋一枝花-张宇
  20. matlab画列车运行图,列车运行图常用画法的具体方法是什么?

热门文章

  1. Java Agent探针技术
  2. C#交换两个变量值的多种写法
  3. Java实现了任意位置截屏(仿QQ截图)
  4. 《终身成长》笔记七——建设性的批评
  5. android密码sha256解密,如何使用密钥字符串解密SHA-256加密字符串?
  6. 数据分析数字取证-attack 中职网络安全
  7. 图形编程中,旋转的三种表示方法
  8. 计算机视觉技术在现代社会中的应用
  9. 汇编——数组求和(适合初学者)
  10. 【usb】linux内核USB键盘驱动解析--特殊键值转化及上报