算法——数论整理
本帖持续更新
这是编程算法计算加速总结
快速乘法
思路
假设当前计算a*b,应用二进制,将a,b中较大的一位数转化为二进制表示,例如11转化为1011,然后类比利用竖式计算乘法那样,用较小的数乘以每一位代表的2次幂,最后相加。
加速点
乘法转为logn量级的乘法+加法
代码
无取模
1 | unsigned long long Imul(unsigned long long a, unsigned long long b) |
取模
1 | unsigned long long Imul(unsigned long long a, unsigned long long b,unsigned long long mod) |
快速幂
思路
类似于快速乘法,同样利用二进制,这里利用的是幂次的二进制位。
例如: $ 7^{11} $ ,幂次的二进制位为:1011,因而可以拆分为: ${7^8} \times {7^2} \times 7$ ,而这些幂次都可通过7的不断自乘得到。只需乘6次即可得到结果。
加速点
利用二进制的特性,直接不断自乘本身即可得到结果,可以跳过一些次幂的运算。
代码
1 | M* Mpow(M* m, unsigned long long n) |
快速斐波那契数列
思路
$$\left[ {\matrix{ {f(2)} & {f(1)} \cr 0 & 0 \cr } } \right] \times {\left[ {\matrix{ 1 & 1 \cr 1 & 0 \cr } } \right]^{n - 2}} = \left[ {\matrix{ {f(n)} & {f(n - 1)} \cr 0 & 0 \cr } } \right]$$其中, ${\left[ {\matrix{ 1 & 1 \cr 1 & 0 \cr } } \right]^{n - 2}}$ 可以用快速幂计算
代码
1 | unsigned long long fib(unsigned long long i) |
快速斐波那契求和
公式
$$\sum\limits_{i = 1}^n {f(i)} = f(n + 2) - 1$$买不到的数目
题目
小明开了一家糖果店。他别出心裁:把水果糖包成 4 颗一包和 7 颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是 17。大于 17 的任何数字都可以用 4 和 7 组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
结论
对于方程
1.a,b互质,一定有解且解的数目无穷
2.C是gcd(a,b)的倍数,方程一定有解,且有无穷多解
对于本题
最大不能组合出的数字:n*m-n-m
公约数公倍数
公约数——欧几里得法
思路
假如x,y有最大公约数T,根据最大公约数的定义,则x,y都可以被T整除。同时也有这样一个数学规律:
$$C = {\rm{mx}} \pm {\rm{ny}}$$
这样的C也是可以被最大公约数T整除的。那么假设:
$$\eqalign{
& x > y,x \div y = a...b \cr
& {\rm{b}} = x - a \times y \cr} $$
那么b也是可以被T整除的,这个b小于y,那么我们得到新的两个数,新的x(较大的这个)为y(旧y),新的y为b,这两个的数仍然可以被T整除,且这两个数均小于原数。
我们这样一直重复,会使得x,y越来越小,越接近T,最后成为T:
$$x\% y = 0$$
此时x=y为最大公约数。
公倍数——公约间接法
思路
假设x,y为两数,T为最大公约数,M为最小公倍数,有这样的数学公式:
$$xy = TM$$
代码
1 | void myfunc(int a, int b) |