本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的。同时也希望文章能够让你有所收获,与君共勉!

今天学习大数之间的加减乘除,我们知道通常整型变量的存储范围为-2147483648~2147483647,当两个数值的操作结果大于这个数时就会溢出。因此为了解决这个问题,我们可以使用vector(数组)的方式去模拟四则运算的计算过程,将结果存储在容器内,从而避免溢出的风险。

高精度加法

代码实现

  1. vector<int> add(vector<int> &A,vector<int> &B){ // A>0,B>0
  2. if(A.size() < B.size()) return add(B,A); // A一定是长度最长的数字.
  3. vector<int> C;
  4. int t = 0; // 当前位上的数
  5. for(int i=0; i < A.size() ; ++i)}{
  6. t += A[i]; // A的对应位加上一位的余数
  7. if(i < B.size()) t += B[i]; // 如果B还存在,就取B对应位进行计算
  8. C.push_back(t%10); // 结果对应位上的数
  9. t / = 10; // 取其余数作为进位数
  10. }
  11. if(t) C.push_back(t); // 如果最后一位相加还有余数就继续存储
  12. return C;
  13. }

高精度减法

代码实现

  1. voctor<int> sub(vector<int>&A,vector<int> &B){ // 注意:一定是A更长且A>= B,A>0,B>0
  2. vector<int> C;
  3. int t = 0;
  4. for(int i=0; i < C.size() ; ++i){
  5. t = A[i] - t; // 减去上一位所借的数
  6. if(i<B.size()) t -= B[i] ; // 如果B还存在
  7. C.push_bakc((t + 10) % 10); //+10是为了防止是负数
  8. if(t < 0) t = 1; // 要向下一位借1
  9. else t = 0; // 对下一位没影响
  10. }
  11. while(C.size() > 1 && C.back() == 0) C.pop_back();
  12. // 如果最后一位刚好位0,则删除最后一位。且不会小于0。因为A >= B
  13. return C;
  14. }

高精度乘法

代码实现

  1. voctor<int> mul(vector<int>&A,int b){ // 注意:这是高精度乘低精度的,即A用vector装,b用int装,且A>0,b>0
  2. vector<int> C;
  3. int t = 0;
  4. for(int i=0 ; i<A.size() && t ; ++i){ // &&t是为了最后一位相乘的结果是多位可以在这个循环里就给他挨个存储到C里面
  5. if(A.size() > i) t += A[i] * b; // 如果A没有乘尽,依然是对位相乘
  6. C.push_back(t%10); // 将该位上的值存在C中
  7. t/=10; // 舍去个位,取得进位
  8. }
  9. while(A.size()> 1 && C.back() == 0) C.pop_back();
  10. return C;
  11. }

高精度除法

代码实现

  1. vector<int> div(vector<int> &A,int b) { // 依然是高精度除低精度的且A.0,b>0
  2. vecotr<int> C;
  3. int t = 0;
  4. for(int i=A>size()-1 ; i >= 0 ; --i){ // 模拟除法都是先运算高位的
  5. t = t*10 + A[i]; // 下一位不都是上一位的余数*10在加上这一位嘛,余数最多也才到9
  6. C.push_back(t/b) // 当第一位比b小时,就会取0,反转过来就会产生后置0,因此后面也要去0
  7. t%=b;
  8. }
  9. reverse(C.begin(),C.end());
  10. while(C.size() > 1 && C.back() == 0) C.pop_back();
  11. return C;
  12. }

啊,难受,中午一点开始弄到一半被叫去实习,磨了一下午的锤子,终于磨完了,本以为能休息会,没想到又要弄车床,时间就这样流逝了,我美好的星期五啊!!!

好了,所以晚上回来特地多写一些模板,多复习一点吧。

前缀和与差分

由于本人还没有学习Latex的数学公式,而且我感觉在markdown上面直接敲推导公式数学符号也太难看了,所以各位就请自己去寻找更详细的内容吧,

这里主要来说一下前缀和和差分能用来干什么。

我们很容易的知道,在一维数组a,b中,当我们想要知道数组a中一段连续区间[i,j]的和时,我们需要去遍历这段区间,时间复杂度为O(n),这时我们可以使用一维前缀和,它可以帮我们用O(1)的时间复杂度求解出来。表达式如下:

\[a[i,j] = b[j] - b[i-1]
\]

当我们需要对区间[i,j]中的每一个数字都进行加减r操作时,时间复杂度为O(n),我们可以使用一维差分,时间复杂度为O(1)。以加法为例,表达式如下:

\[b[i] = b[i] + r
\]
\[b[j+1] = b[j+1] - r
\]

注意更改完后要对差分数组求一维前缀和才会得到对原数组进行操作后的新数组。

二维数组的情况类似,只不过二维前缀和是一个矩阵内所有数字的和,假设二维数组a,b,区间[x_1,y_1]~[x_2,y_2]的二维前缀和的公式如下:

\[s = b[x_2][y_2]-b[x_1-1][y_1-1]
\]

构造前缀和的公式为:

\[b[i][j] = a[i-1][j] + a[i][j-1] + a[i][j] - a[i-1][j-1]
\]

二维差分也与一维差分类似,功能上是对一个矩阵内的元素都加减r,以加法为例,对区间[x_1,y_1]~[x_2][y_2]其公式为:

\[b[x_1][y_1] += r
\]
\[b[x_1][y_2+1] -= r
\]
\[b[x_2+1][y_1]-=r
\]
\[b[x_2+1][y_2+1] += r
\]

同时也要注意对二维差分数组求二维前缀和才是更改后的新数组。

写完都11点了,离谱~~~~!

2022-11-04 Acwing每日一题的更多相关文章

  1. CISP/CISA 每日一题 11

    CISA 每日一题(答) 一个合理建造的数据仓库应当支持下列三种基本的查询格式: 1.向上溯源和向下溯源——向上溯源是对数据进行总计:向下溯源是将数据进行细化: 2.交叉溯源——通过通用属性访问数据仓 ...

  2. 老男孩IT教育-每日一题汇总

    老男孩IT教育-每日一题汇总 第几天 第几周 日期 快速访问链接 第123天 第二十五周 2017年8月25日 出现Swap file….already exists以下错误如何解决? 第122天 2 ...

  3. 【Java每日一题】20161122

    package Nov2016; import java.util.ArrayList; import java.util.Iterator; public class Ques1122 { publ ...

  4. How to Write and Publish a Scientific Paper: 7th Edition(科技论文写作与发表教程)(11.04更新)

    How to Write and Publish a Scientific Paper: 7th Edition(科技论文写作与发表教程)(11.04更新) 重要通知: 最近开题报告已差不多告一段落, ...

  5. CISP/CISA 每日一题 五

    CISA 每日一题(答) 信息系统审计师要确认系统变更程序中的: 1.变更需求应有授权.优先排序及跟踪机制: 2.日常工作手册中,明确指出紧急变更程序: 3.变更控制程序应同时为用户及项目开发组认可: ...

  6. [每日一题]ES6中为什么要使用Symbol?

    关注「松宝写代码」,精选好文,每日面试题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目 ...

  7. [每日一题]面试官问:谈谈你对ES6的proxy的理解?

    [每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  8. 【js】Leetcode每日一题-完成所有工作的最短时间

    [js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...

  9. 【JavaScript】Leetcode每日一题-青蛙过河

    [JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...

  10. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

随机推荐

  1. WebGPU实现Ray Packet

    大家好~本文在如何用WebGPU流畅渲染百万级2D物体?基础上进行优化,使用WebGPU实现了Ray Packet,也就是将8*8=64条射线作为一个Packet一起去访问BVH的节点.这样做的好处是 ...

  2. PHP8中match新语句的操作方法

    PHP8 新出的一个语法很好用,就是 match 语句.match 语句跟原来的 switch 类似,不过比 switch 更加的严格和方便 原来的 switch 语句代码如下: 1 function ...

  3. 解决element-ui中组件【el-upload】一次性上传多张图片的问题

    element-ui 中的组件 el-upload默认的行为是一张图片请求一次,在项目需求中,通常是多张图片要求只向后台请求一次,下面的做法就是为了实现这样的需求 前端 <el-upload r ...

  4. 最新一线大厂Redis使用21条军规及详细解读

    说明:个人原创,本人在一线互联网大厂维护着几千套集群,关于redis使用的一些坑进行了经验总结,希望能给大家带来一些帮助 适用场景:并发量大.访问量大的业务 规范:介绍军规内容 解读:讲解军规设置原因 ...

  5. js之页面列表加载常用方法总结

    导语:最近由于一些事情需要处理,所以没来得及写技术总结了.今天终于可以坐下来好好的梳理一下脉络,说一下那个在日常前端开发过程中,常用到的页面列表加载的方法总结.这里介绍三种方法,分别是分页加载.按钮加 ...

  6. 《Win10——如何进入高级启动选项》

    Win10--如何进入高级启动选项       第一种方法: 管理员命令提示符输入如下代码,自动重启并进入高级启动选项. shutdown /r /o /f /t 00     第二种方法: 1. 管 ...

  7. Python数据科学手册-Numpy数组的计算,通用函数

    Python的默认实现(CPython)处理某些操作非常慢,因为动态性和解释性, CPython 在每次循环必须左数据类型的检查和函数的调度..在编译是进行这样的操作.就会加快执行速度. 通用函数介绍 ...

  8. 从Java 9 到 Java 17 新特性梳理

    Java 9 新的创建集合的方法  // [1, 2, 3, 4]  List<Integer> integers = List.of(1, 2, 3, 4);  // {1,2,3}   ...

  9. ProxySQL介绍

    介绍 ProxySQL是用C++语言开发的,一个轻量级开源软件,性能和功能满足读写中间件所需的绝大多数功能,其配置数据基于SQLite存储,目前已到v2.4.1版本. 功能方面如下: 最基本的读/写分 ...

  10. MySQL 自增字段取值

    1 前言 本文来自回答思否网友的一个问题,这个网友新建了一张表,auto_increment_increment设为10,AUTO_INCREMENT主键起始值设为9, 当他插入数据的时候,发现主键值 ...