- gcd(a,b)=gcd(a+b,b)
- 方程 ax + by = m 有解的必要条件是 m mod gcd(a,b) = 0
- 位运算技巧
- 参考文章:这里
欧几里得距离:两点的直线距离
二维:dis=sqrt( (x1-x2)^2 + (y1-y2)^2 )
三维:dis=sqrt( (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2 )
曼哈顿距离:两个点在标准坐标系上的绝对轴距总和
dis=abs(x1-x2)+(y1-y2)
切比雪夫距离:各坐标数值差的最大值
dis=max(abs(x1-x2),abs(y1-y2))
// time:O(logN)
// 这里不考虑指数为负数的情况
typedef long long ll;
ll pow(ll a, ll b, ll m){
ll ans = 1;
while(b > 0){
if(b & 1){
ans = ans * a % m;
}
a = a * a % m;
b >>= 1;
}
return ans%m;
}
- 慢速乘,求a*b ,比直接相乘快
typedef long long ll;
ll mull(ll a,ll b,ll p)
{
ll res=0;
while(b)
{
if(b&1)res=(res+a)%p;
a=(a+a)%p;
b=b>>1;
}
return res;
}
-
log()是 以e为底
log2() 以2为底
log10() 以10为底 -
乘法逆元 点击 这里 查看
若在mod p意义下,对于一个整数a,有a*b≡1(mod p),那么这个整数b即为a的 乘法逆元,同时a也为b的乘法逆元
一个数有逆元的充分必要条件是gcd(a,p)=1,此时a才有对p的乘法逆元
求取 (a/b)%p 等同于 求取 a∗(b的逆元)%p -
循环小数转化为分数
-
一个线段中的整点个数为gcd(x,y);假设两个端点分别为(x1,y1),(x2,y2),那么线段中整点的个数为 gcd(x2-x1,y2-y1)
证明:这里 -
数字根,这里
-
皮克定理 这里
计算格子多边形面积 S = a + b/2 - 1
a为格子内部的点,b为边界的点 -
斐波那契数列
- n 比较小的时候,可以直接使用过递归法求解,不做任何记忆化操作,时间复杂度是 O(2^n),存在很多冗余计算。
- 一般情况下,我们使用「记忆化搜索」或者「迭代」的方法,实现这个转移方程,时间复杂度和空间复杂度都可以做到 O(n)。
- 为了优化空间复杂度,我们可以不用保存 f(x - 2) 之前的项,我们只用三个变量来维护 f(x)、f(x - 1) 和 f(x - 2),你可以理解成是把「滚动数组思想」应用在了动态规划中,也可以理解成是一种递推,这样把空间复杂度优化到了 O(1)
- 随着 n 的不断增大 O(n)可能已经不能满足我们的需要了,我们可以用「矩阵快速幂」的方法把算法加速到 O(logn)。
我们也可以把 n 代入斐波那契数列的通项公式计算结果,但是如果我们用浮点数计算来实现,可能会产生精度误差。