尤拉函式與線性篩模板
阿新 • • 發佈:2018-11-29
程式碼例項:求單個尤拉函式。分解單個數,可以用迴圈來實現,不必藉助輔助陣列。
//求尤拉函式phi #include<iostream> #include<cstring> using namespace std; int phi(int n){ int ans = n; for(int i = 2;i*i < n;i++){ if(n%i == 0) ans = ans/i*(i-1); while(n%i == 0) n/=i; } if(n > 1) ans = ans/n*(n-1); return ans; } int main(){ int n; cin >> n; cout << phi(n) << endl; return 0; }
線性篩求尤拉函式:
O(N)素數篩:
#include<iostream> using namespace std; const int maxn = 100000; int v[maxn],primes[maxn]; int main(){ int cnt = 0; for(int i = 2;i < maxn;i++){ if(!v[i]){ primes[cnt++] = i; v[i] = i; } for(int j = 0;j < cnt;j++){ if(primes[j] > v[i] || primes[j]*i > maxn) break; v[i*primes[j]] = primes[j]; } } for(int i = 0;i < cnt;i++) cout << primes[i] << " "; return 0; }
在素數篩基礎上改成尤拉篩:
#include<iostream> using namespace std; const int maxn = 100000; int v[maxn],primes[maxn],phi[maxn]; int main(){ int cnt = 0; for(int i = 2;i < maxn;i++){ if(!v[i]){ primes[cnt++] = i; v[i] = i; phi[i] = i-1; } for(int j = 0;j < cnt;j++){ if(primes[j] > v[i] || primes[j]*i > maxn) break; v[i*primes[j]] = primes[j]; phi[i*primes[j]] = phi[i]*(i%primes[j] ? primes[j]-1 : primes[j]); } } for(int i = 2;i < cnt;i++) cout << phi[i] << " "; return 0; }