boolis_prime(int x) { if (x < 2) returnfalse; for (int i = 2; i <= x / i; i ++ ) if (x % i == 0) returnfalse; returntrue; }
试除法分解质因数
1 2 3 4 5 6 7 8 9 10 11 12
voiddivide(int x) { for (int i = 2; i <= x / i; i ++ ) if (x % i == 0) { int s = 0; while (x % i == 0) x /= i, s ++ ; cout << i << ' ' << s << endl; } if (x > 1) cout << x << ' ' << 1 << endl; cout << endl; }
朴素筛法求素数
求2~n所有素数
1 2 3 4 5 6 7 8 9 10 11 12 13
int primes[N], cnt; // primes[]存储所有素数 bool st[N]; // st[x]存储x是否被筛掉
voidget_primes(int n) { for (int i = 2; i <= n; i ++ ) { if (st[i]) continue; primes[cnt ++ ] = i; for (int j = i + i; j <= n; j += i) st[j] = true; } }
优化(小于x^2的x的倍数在扫描更小的数的时候已经被标记过了)
1 2 3 4 5 6 7 8 9 10 11 12 13
int primes[N], cnt; // primes[]存储所有素数 bool st[N]; // st[x]存储x是否被筛掉
voidget_primes(int n) { for (int i = 2; i <= n; i ++ ) { if (st[i]) continue; primes[cnt ++ ] = i; for (int j = i; j <= n/i; j ++) st[i*j] = true; } }
线性筛法求素数
保证每个数被它的最小质因子筛掉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int primes[N], cnt; // primes[]存储所有素数 bool st[N]; // st[x]存储x是否被筛掉
voidget_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; //primes[j]小于等于i的最小质因子 if (i % primes[j] == 0) break; //保证primes[j]小于等于i的最小质因子 } } }
约数
定义
若整数n除以整数d的余数为0,即d能整除n,则称d是n的约数,n是d的倍数
试除法求所有约数
1 2 3 4 5 6 7 8 9 10 11 12
vector<int> get_divisors(int x) { vector<int> res; for (int i = 1; i <= x / i; i ++ ) if (x % i == 0) { res.push_back(i); if (i != x / i) res.push_back(x / i); } sort(res.begin(), res.end()); return res; }
intphi(int x) { int res = x; for (int i = 2; i <= x / i; i ++ ) if (x % i == 0) { res = res / i * (i - 1); while (x % i == 0) x /= i; } if (x > 1) res = res / x * (x - 1);
// 求x, y,使得ax + by = gcd(a, b) intexgcd(int a, int b, int &x, int &y) { if (b == 0) { x = 1; y = 0; return a; } int d = exgcd(b, a % b, x, y); int t = x; x = y; y = t - (a / b) * y; return d; }