题目描述
给定 个正整数 ,请你求出每个数的欧拉函数。
输入格式
第一行包含整数 。
接下来 行,每行包含一个正整数 。
输出格式
输出共 行,每行输出一个正整数 的欧拉函数。
数据范围
,
输入样例:
3
3
6
8
输出样例:
2
2
4
题目分析
这是一道关于求解欧拉函数的问题,欧拉函数是数论中的一个很基础的概念。
首先我们来看一下欧拉函数的定义及求解方式:
我们将 1∼N 中与 N 互质的数的个数被称为欧拉函数,记为 ϕ(N)。
若在算数基本定理中,,则我们不加证明的给出欧拉函数的求解方式:
ϕ(N) =
关于欧拉函数的证明方式,我们一般采用容斥原理的方式,在这里我们不再展开证明,而更重于本题的解题步骤。
首先对于一个数 ,我们要求取它的所有质数。这里我们采取试除法的方式,即从 开始枚举到 ,对于能被当前 整除的枚举数,需要将 一直除以这个数一直到无法整除,并记录这个数,在模拟的过程中我们可以知道,这个数一定是一个质数,而在后续对更大的数的枚举过程中,一定不会枚举到一个合数(因为在之前枚举到这个合数的最小质因数时已经对 进行了除法操作)。最终按要求求取答案即可。
由于每个数 在最坏情况下会产生 次枚举,则最终时间复杂度为 。
Accept代码
#include <iostream>
#include <vector>
using namespace std;
vector<int> v;
void phi(int n)
{
int res = n;
for (int i = 2; i <= n / i; i ++)
{
if (n % i == 0)
{
while (n % i == 0)
{
n /= i;
}
v.push_back(i);
}
}
if (n > 1) v.push_back(n);
for (auto i : v)
{
res = 1ll * res * (i - 1) / i;
}
cout << res << '\n';
v.clear();
}
int main()
{
int t;
cin >> t;
while (t --)
{
int a;
cin >> a;
phi(a);
}
return 0;
}