先介绍欧拉函数及其相关定理吧:
1.欧拉函数:对于任意一个数X,将其分解质因数为X=(P1^b1)*(P2^b2)*(P3^b3)......
则小于X的与X互质的数的个数N为N = X * (1 - 1 / p1) * (1 - 1 / p2).......
显然对于质数p,Euler(p) = p - 1;
2.一个数的所有质因子之和是euler(n)*n/2;
3.a^Euler(n) % n = 1,这里可以用模运算来证明;
具体实现:
1.先筛素数
2.从2开始遍历素数,能整除则乘,然后将之除尽
附上代码:
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <string> #include <math.h> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #pragma warning(disable:4996) #define Zero(a) memset(a, 0, sizeof(a)) #define Neg(a) memset(a, -1, sizeof(a)) #define All(a) a.begin(), a.end() #define PB push_back #define repf(i,a,b) for(i = a;i <= b; i++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define root 1,n,1 #define ld rt << 1 #define rd rt << 1 | 1 #define ll long long #define MAXN 100005 #define mod 10007 using namespace std; int prime[MAXN]; int isNotPrime[MAXN]; void get_prime(){ int num_prime = 0; isNotPrime[0] = isNotPrime[1] = 1; for (int i = 2; i < MAXN; i++){ if (!isNotPrime[i]) prime[num_prime++] = i; for (int j = 0; j < num_prime && i * prime[j] < MAXN; j++) { isNotPrime[i * prime[j]] = 1; if (!(i % prime[j])) break; } } } vector <int >ok; int main(){ get_prime(); //cout << prime[0] << endl; int n; while (~scanf("%d", &n)){ ok.clear(); int ans = n; for (int i = 0; prime[i] <= n; ++i){ if (n % prime[i] == 0){ ok.push_back(prime[i]); while (n % prime[i] == 0) n /= prime[i]; } } //cout << ok.size() << endl; for (int i = 0; i < ok.size(); ++i){ //cout << ok[i] << endl; ans *= (ok[i] - 1); ans /= ok[i]; } printf("%d\n", ans); } return 0; }
时间: 2024-10-15 01:30:07