boolis_prime(int n){ // judge if n is a prime number if(n <= 1) returnfalse; // 1 and less are not prime numbers for(int i=2; i*i <= n; i++) { if(n%i == 0) { returnfalse; // n is divisible by i, so it's not a prime number } } returntrue; // n is a prime number }
素数表的构建:构建素数表,同时确认范围内的所有数是否为素数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include<iostream> #include<vector>
usingnamespace std;
vector<bool> is_prime(int n){ vector<bool> prime(n+1, true); // Create a vector to store prime status prime[0] = prime[1] = false; // 0 and 1 are not prime numbers for(int i=2; i*i <= n; i++) { if(prime[i]) { // If i is prime for(int j=i*i; j<=n; j+=i) { prime[j] = false; // Mark multiples of i as not prime } } } }
vector<bool> linear_sieve(int n){ vector<bool> prime(n+1, true); vector<int> primes; // Store the prime numbers prime[0] = prime[1] = false; // 0 and 1 are not prime numbers for(int i=2; i<n; i++) { if(prime[i]) { primes.push_back(i); // i is a prime number } for(int j=0; j<primes.size() && primes[j] < n/i; j++) { prime[primes[j]*i] = false; // Mark multiples of primes as not prime if(i % primes[j] == 0) break; } } return prime; }
欧拉函数
欧拉函数 ϕ(n) 是指小于等于 n 的正整数中,与 n 互质的数的个数。
欧拉函数的计算
欧拉函数可以通过以下公式计算:
ϕ(n)=n(1−p11)(1−p21)⋯(1−pk1)
其中 p1,p2,…,pk 是 n 的所有不同的质因数。
暴力法
时间复杂度:O(n)
算法思想:逐个计算每个质因数,代入上述公式中计算,找到一个质因数之后需要将 n 除以该质因数,直到 n 不能被该质因数整除为止。最后如果 n 仍然大于1,则 n 本身也是一个质因数,需要再进行一次计算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#include<iostream> #include<vector>
usingnamespace std;
intget_euler(int n){ int res = n; for(int i=2; i*i <= n; i++) { if(n % i == 0) { res = res / i * (i-1); while(n%i == 0) { n /= i; // Remove all factors of i from n } } } // If n is still greater than 1, it is a prime factor return n > 1 ? res / n * (n-1) : res; }
线性筛法
时间复杂度:O(n)
算法思想:使用线性筛法计算素数,然后利用素数计算欧拉函数。对于每个素数 p,如果 p 是 n 的质因数,则 ϕ(n)=n×(1−p1),否则 ϕ(n)=ϕ(n)。