int能表示范围为2^32,这看起来很大,但在大数据时代的如今,不说是int 哪怕是long long也是不够的,那么为了使用或计算这些超出或远超整形大小的数,我们这些数的计算方法称为高精度计算。
我们采用的方法是开两个数组A,B,然后用这两个数组来模拟两个大数之间的加法运算。代码实现要注意两个细节:
①实现过程中一定要保证A的长度大于B
②实现过程中注意数的存储顺序是从低位向高位,具体过程如下所示:
代码如下所示:
vector<int> add(vector<int> &A, vector<int> &B) { if (A.size() < B.size()) return add(B, A); vector<int> C; int t = 0;//t用于表示进位 for (int i = 0; i < A.size(); i ++ ) { t += A[i]; if (i < B.size()) t += B[i]; C.push_back(t % 10); t /= 10; } if (t!=0) C.push_back(t);//用于保存进位 return C; }
思路和高精度加法基本一致,只是模拟的过程是减法而不是加法
vector<int> sub(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = 0, t = 0; i < A.size(); i ++ ) { t = A[i] - t; if (i < B.size()) t -= B[i]; C.push_back((t + 10) % 10); if (t < 0) t = 1; else t = 0; } while (C.size() > 1 && C.back() == 0) C.pop_back(); //去掉首位的所有0 return C; }
前缀和是一种重要的预处理,能大大降低查询的时间复杂度。前缀和是以求和的方式灵活地面对区间询问。例如以下问题:
给你一串长度为 n 的数列 a1, a2, a3, …, an,再给出 m 个询问,每次询问给出 L, R 两个数,要求给出区间 [L, R] 里的数的和。如果使用前缀和处理以后很容易可以得到
则
上
述
题
目
的
结
果
为
S
[
L
]
−
S
[
R
−
1
]
则上述题目的结果为S[L]-S[R-1]
则上述题目的结果为S[L]−S[R−1]
时间复杂度显然降低
①一维前缀和(用于处理一维数组)
表
达
式
为
S
[
n
]
=
a
1
+
a
2
+
a
3
+
.
.
.
.
a
n
预
处
理
递
推
公
式
为
:
S
[
n
]
=
S
[
n
−
1
]
+
a
n
表达式为S[n]=a_1+a_2+a_3+....a_n\\预处理递推公式为:S[n]=S[n-1]+a_n
表达式为S[n]=a1+a2+a3+....an预处理递推公式为:S[n]=S[n−1]+an
②二维前缀和(用于处理二维数组)
二维前缀和的公式如下
二
维
前
缀
和
表
达
式
为
:
S
[
x
,
y
]
=
∑
i
=
1
x
∑
i
=
0
y
a
i
j
预
处
理
递
推
公
式
为
:
S
[
x
,
y
]
=
S
[
x
−
1
,
y
]
+
S
[
x
,
y
−
1
]
−
S
[
x
−
1
,
y
−
1
]
+
a
x
y
二维前缀和表达式为:S[x,y]=\sum_{i=1}^x\sum_{i=0}^ya_{ij}\\预处理递推公式为:\\S[x,y]=S[x-1,y]+S[x,y-1]-S[x-1,y-1]+a_{xy}
二维前缀和表达式为:S[x,y]=i=1∑xi=0∑yaij预处理递推公式为:S[x,y]=S[x−1,y]+S[x,y−1]−S[x−1,y−1]+axy
这个公式可以根据以下方法记忆:
代码实现思路如下:
(1)初始化所有的S[n][0],S[0][m](第一行与第一列)
(2)根据递推公式推出所有的S[x][y]