ACwing:算法基础课 第一章高精度,前缀和,差分听课笔记

ios::sync_with_stdio(false);//提高cin的速度,加了这个语言之后就不能再用scanf

一。 高精度

1⃣️大整数加大整数
1。位数:位数是1E6
2。存储:用数组存大整数的的每一位,然后数组的第一个位置存大整数的个位
3。运算:模拟脱式计算过程,注意是除以模的余数
4。注意输入输出的处理,用Vector来存更好。因为可以自己延长,学会auto变量
5。循环选择两个整数位数更长的那个作为结束条件

2⃣️大整数减大整数
1。存储:仍然是用数组 在这里插入图片描述

2。减数:减法的时候都是大减去小,如果是减去大的话,就return回这两个数的位置掉转过来的函数,然后再加个负号就行。因此在进行减法的运算的时候,要先判断这两个数是大减小还是小减大,如果是小减大的话,就return掉转一下然后添一负号。

3。如何判断两个大整数的大小,即如何比较两个大整数:
1⃣️先判断位数
2⃣️若位数相同则从高位开始比,第一个高位不相等的,则就可以判断出哪个大哪个小了。若全部位数相同,则全部相同

4。若是负数相减,或者正减去负,则输入输出的时候做好存储,因为所用的运算都可以转化成绝对值相加或者相减,然后套用模版

5。模版中(t+10)%10的原因在这里插入图片描述

vector<int> sub(vector<int>&A,vector<int>&b)
{

vector C;
for(int i=0,t=0;i<A.size();i++{
t=A[i]-t;//先将被减数减去借位,注意,这个减去的t一开始是充当借位的作用,减去后,剩下的t则是第一位数减去借位后剩下的值
if(i<B.size()) t=t-B[i];//检查是否越界,如果不越界,即被减数还有位置,则继续减
C.push_back((t+10)%10);//包含了减去减数之后正数和负数的两种情况。
if(t<0) t=1;
else t=0;
}
return C;
}

3⃣️大整数乘小整数

1。运算,他是用大整数的每一位去乘以小精度的,然后取模剩下的就是乘出来的结果,然后再进行进位

4⃣️ 大整数除以小整数
求商和余数
1。运算:每一位的余数等于上一位的余数乘10加上下一位数
2。注意本来除法从高位存到低位比较好的,但是为了与前面的保持一致,所以还是从个位存
3。由于最后除出来的存的结果是从高位到低位的,但是main函数中输出的结果是从低往高输出的,所以要reserves一下

二。前缀和

1。意义:便于更快的求出原数组任意区间内的值 [l,r],闭区间

2。下标注意:前缀和数组的下标不要从1开始表示,开始存数据,便于统一,即S0默认是等于0。原数组要从1开始存数据

3。前R个数的和减去前L-1个数的和结果就等于L~R区间的数的和,闭区间[L,R]

⚠️!!!学到了:在需要读取数据时,即用到CIN 的时候可以加上一段话:

ios::sync_with_stdio(false);

作用时提高CIN 的速度,副作用就是不可以再用SCANF了

输入数据大于一百万的时候用SCANF,否则就用C IN

5。怎么求前缀和数组:
在这里插入图片描述

三。二维前缀和

1。若要要想快速的求出来某一个矩阵的集群的和的话就可以用二维前缀和

2。Sij表示它左上角矩阵所有元素的和

3。假如要求蓝色矩形的元素和
在这里插入图片描述

4。如何求原矩阵的前缀和Sij,也是从0开始,S00默认为0。注意:原矩阵为a,且从a(1,1)开始存数据。
利用两重for循环:
for(i=1:n)
for(j=1:n)
Sij=S(i-1,j)+S(i,j-1)-S(i-1,j-1)+a(i,j)
在这里插入图片描述

5。已知了原矩阵前缀和Sij,如何求原矩阵中任意子矩阵的元素和:
如:要求如下图以x2,y2为右下角,x1,y1为左上角的矩阵和的公式:
Sum=S(x2,y2)-S(x2,y1-1)-S(x1-1,y2)+S(x1,y1)

注意:前缀和是闭区间的,所以S(x2,y1-1)代表了红色的那个矩阵,不包括下边界,因为下边界矩阵是属于待求矩阵的;S(x1-1,y2)表示紫色的那个矩阵,不包括有边界,因为右边界元素是属于待求的矩阵的。
在这里插入图片描述

三。差分数组

1。定义:已知a数组,然后构造B 数组,使得A数组是B 数组的前缀和,即A[I]=B[1]+b[2]+…+B[i]
此时 B数据就称为差分数组

2。差分数组的作用:
1⃣️如果已经有了差分数组,则只需要对差分数组求一遍前缀和就可以得出原数组的值了
只需要O(N)的时间

2⃣️当对原数组某一区间进行一个全加或者减一个数的时候,利用差分数组可以在O(1)的时间内得出结果
比如:我要A数组的[L,R]区间全部加上C,则只需要在差分数组的B[L]+C,然后在B[r+1]-c即可,这样就可以保证在A数组的[L,R]内才会加,其他区域无影响
在这里插入图片描述

所以只需要修改两个数就好

3⃣️公式:就是截图屏幕里面的两个点更新即可,可以自己推

4⃣️差分数组的构造:通过原数组A[i]构造差分数组B[i]可以看成B[i]在区间[i,i]插入了A[i],所以只需写一个insert函数即可.
Void insert(int l,int r,int c)
{
B[l]=B[l]+c;
B[r+1]=B[r+1]-c
}

5⃣️原数组和前缀和 一样,都是从1下标开始存数据,因为差分数组下标为0的恒为0

3。二维差分

1⃣️定义:让a[i][j] 是b[i][j]的前缀和,差分数组不需要考虑什么时候构造,只需要考虑如何更新即可,因为差分数组初始化成A数组的时候就是可以直接看成是在i~ i区间内插入A【i】

2⃣️B数组的前缀和是A

3⃣️差分数组的公式
自己按照如下图的法分析去推,即只需要更新四个点即可
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值