<cmath>中常用函数
pow(base, exponent)
sqrt(x)
fmax、fmin、fabs
ceil、floor、round(四舍五入)
上述这些返回值和参数默认都是浮点数 注意强制类型转换 注意double强制转int 向下舍入
e.x. %的除数和被除数都必须为整型变量且除数不能为0否则runtime error
abs的返回值虽然是整型,但它同时为整型和浮点型重载,可替代fabs
fmin、fmax是<cmath>中求最值的方法,不过我们通常使用algorithm头文件中的min 、max,后者还可以自定义比较函数模运算
负数取模
e.x. 日期与当前日期的天数差值可能为负
(days % 7 + 7) % 7
加上求模的除数仍要再取一次模,保证原来模为0的情况仍为0大数求模
(a*b) % c = (a % c * b % c) % c
(a+b) % c = (a % c + b % c ) % c
- GCD & LCM
最大公约数 Greatest Common Divisor
欧几里得算法 辗转相除
while( b!= 0) {
int t = a % b;
a = b;
b = t;
}
return a;
最小公倍数 Least Common Multiplea * b / gcd(a,b)
- 素数
- 素数判定
bool isPrime(int x) {
if (x <= 1)
return false;
for(int i = 2; i*i <= x; i++) {
if (x % i == 0) {
return false;
}
}
return true;
}
- 素数筛法
Sieve of Eratosthenes 排除法
O(n*log(log(n)))
bool prime[n+1];
memset(prime, true, sizeof(prime));
for (int p=2; p*p<=n; p++)
{
if (prime[p] == true)
{
// less than p^2 are already been marked.
for (int i=p*p; i<=n; i += p)
prime[i] = false;
}
}
Sieve of Euler 欧拉筛法
O(n)
- 分解质因数
- 数位拆解
do{
} while(a != 0);
可避免数本身为0时未分解到任何结果的情况 - 进制转换
- 注意字符与数字比较时一定记得加单引号'0'
- 注意向字符串转换和从字符串转换时的反序和反向遍历操作
- 注意处理0和负数
从字符串转换时判断s[0] == '-' ,向字符串转换时0和负数的构造
- 高精度
- 高精度加法
vector<int> bigAdd(vector<int>& a, vector<int>& b) {
vector<int> res;
int alen = (int)a.size();
int blen = (int)b.size();
for (int i = 0, g = 0; ; i++) {
if (g == 0 && i >= alen && i > blen) {
break;
}
if (i < alen) {
g += a[i];
}
if (i < blen) {
g += b[i];
}
res.push_back(g % BASE);
g /= BASE;
}
return res;
}
- 高精度乘法
vector<int> bigMul(vector<int>& a, vector<int>& b) {
int alen = (int)a.size();
int blen = (int)b.size();
int index;
for (index = 0; index < a.size() && a[index] == 0; index++) {}
if (index == a.size()) return { 0 };
for (index = 0; index < b.size() && b[index] == 0; index++) {}
if (index == b.size()) return { 0 };
vector<int> res(alen + blen, 0);
// i*j存放i+j
for (int i = 0; i < alen; i++) {
for (int j = 0; j < blen; j++) {
res[i + j] += a[i] * b[j];
}
}
int g = 0;
for (int i = 0; i < (int)res.size(); i++) {
int tmp = res[i] + g;
res[i] = tmp % BASE;
g = tmp / BASE;
}
while (res.back() == 0) {
res.pop_back();
}
return res;
}
- 高精度求模
- 二分求幂
快速幂
矩阵快速幂
mat qPow (mat A, ll n) {
int len = (int)A.size();
mat res(len, vector<BigInt>(len));
res[0][0] = res[1][1] = 1;
res[0][1] = res[1][0] = 0;
while (n) {
if ( n & 1 ) {
res = matrixMultiply(res, A);
}
A = matrixMultiply(A, A);
n >>= 1;
}
return res;
}