数的算法
基本算术
高精度加法
// C = A + B, A >= 0, B >= 0 vector<int> add(vector<int> &A, vector<int> &B) { if (A.size() < B.size()) return add(B, A); vector<int> C; int t = 0; 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) C.push_back(t); return C; }
高精度减法
// C = A - B, 满足A >= B, A >= 0, B >= 0 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(); return C; }
模运算
快速幂。求
$$
typedef long long LL; LL qmi(int a, int k, int p) { LL ret = 1; while (k) { if (k & 1) ret = ret * a % p; k >>= 1; a = (LL)a * a % p; } return ret; }
素数判定
- 质数(素数)
定义:在大于1的整数中,如果只包含1和本身这两个约数,就被称为质数(素数)。小于等于1的数既不是质数,也不是合数。
试除法
bool is_prime(int u) { if (u < 2) return false; for (int i = 2; i <= u / i; i ++ ) { if (u % i == 0) return false; } return true; }
分解质因数–试除法
n中最多只包含一个大于n√n的质因子
最好O(logn),最坏O(√n)
void divide(int n) { for (int i = 2; i <= n / i; i++) { if (n % i == 0) { int cnt = 0; while (n % i == 0) { n /= i; cnt++; } cout << i << ' ' << cnt << endl; } } if (n > 1) cout << n << ' ' << 1 << endl; }
朴素筛质数
O(nlogn)O(nlogn)
int primes[N], cnt; bool st[N]; void get_primes(int n) { for (int i = 2; i <= n; i ++ ) { if (st[i]) continue; primes[cnt ++ ] = i; for (int j = 2 * i; j <= n; j += i) st[j] = true; } }
埃氏筛质数
O(nlog)
void get_primes(int n) { for (int i = 2; i <= n; i ++ ) { if (!st[i]) { primes[cnt ++ ] = i; for (int j = i * 2; j <= n; j += i ) st[j] = true; } } }
线性筛质数
O(n)
nn只会被最小的质因子筛掉,每个数只有一个最小质因子,所以每个数只会被筛一次
当pj∣ipj∣i时,pjpj一定是ii的最小质因子,也一定是pj∗ipj∗i的最小质因子
当pj∤ipj∤i时,pjpj一定小于ii的最小质因子,pjpj也一定是pj∗ipj∗i的最小质因子
void get_primes(int n) { for (int i = 2; i <= n; i ++ ) { if (!st[i]) primes[cnt ++ ] = i; // 从小到大枚举所有质数 for (int j = 0; primes[j] <= n / i; j ++ ) { st[primes[j] * i] = true; if (i % primes[j] == 0) break; } } }
位运算
基本操作
与 & 都为真为真
或 | 有一个为真就为真
非 ! 真的变假,假的变真
异或 ^ 如果相同为0,不同为1
- 未完待续
Hash
- 未完待续。。。