欧拉函数 Totient Extreme-CSDN博客

75 阅读1分钟

欧拉函数

定义:欧拉函数φ(n), 表示小于或等于n的数中,与n互质的数的数目。

\

欧拉函数求值方法:

(1)、φ(1) = 1.

(2)、若n是素数p的k次幂,φ(n) = p ^k - p^(k-1) = (p - 1) * p^(k - 1).

(3)、若m, n互质,φ(mn) = φ(m)*φ(n).

根据欧拉函数的定义,可以求出欧拉函数的递推式:

令p为N的最小质因数, 若p^2 | N, φ(N) = φ(N/p) * p; 否则 φ(N) = φ(N / p) * (p - 1).

const int N = 10000;
int euler[N + 1];
void getEuler(int n) {
	memset(euler, 0, sizeof(euler));
	euler[1] = 1;
	for (int i = 2; i <= n; i++)	if (!euler[i])
		for (int j = i; j <= n; j += i) {
			if (!euler[j])
				euler[j] = j;
			euler[j] = euler[j] / i * (i - 1);
		}
}

\

求单个欧拉数

const int N = 320000;
bool vis[N + 1];
int p[27610], cnt_p; //存素数  27608
int getPrime(int n) {
	memset(vis, 1, sizeof vis);
	int cnt = 0; 
	for (int i = 2; i <= n; ++i) {
		if (vis[i]) 	p[cnt++] = i;  
		for (int j = 0; j < cnt && (i * p[j] <= n); ++j) {
			vis[i * p[j]] = 0;
			if (i % p[j] == 0) break;
		}
	}
	return cnt;
}
vector <long long> work(long long num) {
	vector<long long> vec;
	for (int i = 0; i < cnt_p; ++i) {
		if (num % p[i] == 0) {
			vec.push_back(p[i]);
			while (num % p[i] == 0) num /= p[i];
		}
		if (num <= 1) break;
	} //得到了素因数
	if (num > 1) vec.push_back(num);
	return vec;
}
long long phi(long long n) {
	long long res = n;
	vector<long long> v = work(n);
	for (int i = 0; i < v.size(); ++i) {
		res = res / v[i] * (v[i] - 1);
	}
	return res;
}


\