一.题目链接
二.思路
思路参考:https://www.acwing.com/problem/content/203/
三.代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m;
int primes[N], cnt;
bool st[N];
int phi[N];
//线性筛法求欧拉函数
void init(int n)
{
phi[1] = 1;//第一个不同点
for(int i = 2; i <= n; i ++)
{
if(!st[i])
{
primes[cnt ++] = i;
phi[i] = i - 1;//第二个
//如果i是质数,那么和他互质的数的个数就是 i - 1
}
for(int j = 0; i * primes[j] <= n; j ++)
{
st[i * primes[j]] = true;
if(i % primes[j] == 0)
{
/*如果pj是i的最小质因数
那么 phi[i * pj] = i * pj * p1 * p2 * p3 ..... = pj * phi[i];
*/
phi[i * primes[j]] = phi[i] * primes[j];//第三个
break;
}
/*
如果不是。
phi[i * pj] = i * pj * (1 - 1/pj) * p1 * p2 ....=phi[i] * (pj - 1)
*/
phi[i * primes[j]] = phi[i] * (primes[j] - 1);//第四个
}
}
}
int main()
{
//预处理欧拉函数
init(N);
cin >> m;
for(int i = 1; i <= m; i ++)
{
cin >> n;
//答案:(phi[1] + phi[2] + .... + phi[n]) * 2 + 1;
int res = 1;
for(int i = 1; i <= n; i ++) res += phi[i] * 2;
printf("%d %d %d\n", i, n, res);
}
return 0;
}
四.总结
线性筛求欧拉函数的证明: