I Prime number
1. Determine prime number by trial division
The factors of a number appear in pairs. We can judge the smaller one
It should be noted that I < = sqrt (x) or I * I < = x should not be used as far as possible. First, it is to reduce the operation and second, it is to prevent exceeding the int range
bool is_prime(int x) { if (x < 2)return false; for (int i = 2; i <= n / i; i++) if (n % i == 0)return false; return true; }
2. Decomposition quality factor
According to the basic theorem of arithmetic: each positive integer can be expressed in a unique way by the product of its prime factor
n=p1^a1 * p2^a2 * p3^a3...
If there is a factor greater than Sqn in the multiplication method, it must be proved that there is at most one factor greater than sqrt
For example, if n=16, 16/2 still has a multiple of 2, so it is dried in a circular way. Finally, if n > 1, it means that this is the only prime factor greater than sqrt(n).
void divide(int n) { for (int i = 2; i <= n / i; i++) { if (n % i == 0) { int s = 0;//s is the number of times while (n % i == 0) { n /= i; s++; } cout << i << ' ' << s << endl; } } if (n > 1)cout << n << ' ' << 1 << endl; }
3. Number of sieves
(1) Ordinary sieve method O(nlogn)
Both prime and composite numbers are used to sift out the multiples behind them
void get_primes(int n) { for (int i = 2; i <= n; i++) { if (!st[i])primes[cnt++] = i; for (int j = i; j <= n; j += i)st[j] = true; } }
(2) Angstrom sieve method O(nloglogn)
The principle of Eratosthenes sieve method is that the multiples of any integer x, 2x, 3x,... Are not prime numbers.
However, even so, there will be repeated marking. For example, 12 will be marked by both 2 and 3. When marking the multiple of 2, 12 = 6 * 2, and when marking the multiple of 3, 12 = 4 * 3. The fundamental reason is that there is no unique way to produce 12.
void get_primes(int n) { for (int i = 2; i <= n; i++) { if (!st[i]) { primes[cnt++] = i; for (int j = i; j <= n; j += i)st[j] = true; } } }
(3) Linear sieve method O(n)
n will only be sifted out by his smallest prime factor
If i%primes[j]==0, it means that primes[j] is the minimum prime factor of i and also the minimum prime factor of primes[j]*i. therefore, in order to prevent repeated marking, break can be used
void get_primes(int n) { for (int i = 2; i <= n; i++) { if (!st[i])primse[cnt++] = i; for (int j = 0; primes[j] <= n / i; j++) { st[primes[j] * i] = true; if (i % primes[j] == 0)break; } } }
4. Goldbach conjecture
Any even number greater than 4 can be split into the sum of two odd primes.
Directly enumerate the prime numbers
for (int i = 1;; i++) { int a = primes[i]; int b = n - a; if (!st[b]) { printf("%d = %d + %d\n", n, a, b); break; } }
5. Factorial decomposition
Example: if you calculate 8! Number of 2 in
1 2 3 4 5 6 7 8 1 1 1 1 1 1 1 4 + 2 + 1 = 7
for (int i = 0; i < cnt; i++) { int p = primes[i]; int s = 0; for (int j = n; j; j /= p)s += j / p; cout << p << ' ' << s << endl; }
II Counting
Quick power template:
int qmi(int a, int k) { int res = 1; while (k) { if (k & 1)res = (LL)res * a % mod; a = (LL)a * a % mod; k >>= 1; } return res; }
III Divisor
1. Try division to find the divisor
Paired sieve
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; }
2. Approximate number
(1) Approximate number template
Conclusion: n=p1^a1 * p2^a2 * p3^a3
ans=(a1+1) * (a2+1) * (a3+1)....
Each divisor d can be expressed as
d=p1^b1 * p2^b2 * p3^b3...
There are 0 ~ a1 selection methods in b1 and 0 ~ a2 selection methods in b2
So the approximate number is (a1+1) * (a2+1) * (a3+1)
Please n^ How many divisors are there altogether
(2c1+1)∗(2c2+1)∗...∗(2ck+1)
void divisor(int n) { unordered_map<int, int> hash; for (int i = 2; i <= n / i; i++) { while (n % i == 0) { n /= i; hash[i]++; } } if (n > 1)hash[n]++; int res = 1; for (auto& x : hash)ans *= (x.second + 1) % mod; cout << res << endl; }
(2). Ingenious conversion of divisor and multiple
Divisor and multiple are actually a pair of good friends. When the time of finding divisor is too complex, you might as well consider solving the problem from the perspective of multiple
Example: for each Ai, how many numbers in other numbers are its divisor?
Count the number of Ai occurrences
for(int i = 0; i < n; i++) { scanf("%d", &a[i]); cnt[a[i]]++; } for(int i = 1; i < N; i++) { if(!cnt[i]) continue; //i is actually Ak, and j is a multiple of i for(int j = i; j < N; j += i) { res[j] += cnt[i]; } } Finally, for each res - 1(Delete yourself)
3. Sum of approximations
while (b – ) t = (t * a + 1) % mod;
t=t∗p+1
t=1
t=p+1
t=p^2+p+1
......
t=p^b + p^b-1...+1
void divisor(int n) { unordered_map<int, int> hash; for (int i = 2; i <= n / i; i++) { while (n % i == 0) { n /= i; hash[i]++; } } if (n > 1)hash[n]++; int res = 1; for (auto x : hash) { long long t = 1; while (x.second--)t = (t * x.first + 1) % mod; res = res * t % mod; } cout << res << endl; }