题目
题解思路
欧拉函数是小于或等于n的正整数中与n互质的数的数目
phi[ 1 ] = 1
我们可以在筛法的中间穿插欧拉函数的求法。
很显然 在筛法 首先出现的素数们的欧拉函数值肯定是 i - 1 ,它一定对前面出现的数都互质。(因为它能组成的合数还没出现)
欧拉筛是用之前出现的素数来筛这个数组合成的合数,当发现是素数是这个数的最小质因子的时候就break。
运用这个公式我们能递推出合数的欧拉函数转移方程。
下面的题解提供了推导过程。
然后回到这题
斜率y/x必然互质 ,这样才能保证他们不会出现相同的点的情况。
坑点,x y 可以为0 。
这样我们让 1 0 0 1 去走 x y 轴 再让 1 1 走 对称轴
这样剩下的就是 对 2 到 N 欧拉函数值求和 * 2 了
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 200100;
bool st[N] ;
int prm[N] ;
int hi[N] ;
int cnt ;
void in (int n )
{
cnt = 1 ;
st[1] = 1 ;
hi[1] = 1 ;
for (int i = 2 ; i <= n ; i++ )
{
if ( ! st[i] )
{
prm[cnt] = i ;
cnt++ ;
hi[i] = i - 1 ;
}
for (int j = 1 ; i*prm[j] <= n ; j++ )
{
st[i*prm[j]] = 1 ;
if ( i % prm[j] == 0 )
{
hi[i*prm[j]] = hi[i] * prm[j] ;
break;
}
hi[ i*prm[j] ] = hi[i] * ( prm[j] - 1 ) ;
}
}
}
int main ()
{
ios::sync_with_stdio(false);
int T ;
in(1010);
cin >> T;
int tt = 1 ;
while( T-- )
{
int n ;
int ans = 0 ;
cin >> n ;
for (int i = 1 ; i <= n ; i++ )
{
ans += hi[i] ;
// cout << hi[i] <<" ";
}
cout<< tt << " " << n << " " << 2*ans + 1 << "\n";
tt++;
}
return 0 ;
}