题目链接:
http://acm.hust.edu.cn/vjudge/contest/70017#problem/O
题意:
给定一个正整数N
(N<4000000)
, 求
G=∑i<Ni=1∑j≤Nj=i+1gcd(i,j)
的值
分析
已知
f(N)=gcd(1,N)+gcd(2,N)+⋯+gcd(N−1,N)
即
j=N,f(N)=∑i<Ni=1gcd(i,N)
则结果为
f(2)+f(3)+f(4)+⋯+f(N)
即
ans=∑i≤Ni=2f(i)
根据gcd性质,若
gcd(k,n)=i
,则必有
gcd(k/i,n/i)=1
,即
k/i与n/i
互质,
那么枚举
i
的值,
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <set>
#define MOD 1000000007
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
/*---------------------------head files----------------------------------*/
const int maxn = 4000009 ;
int phi[maxn], prime[maxn / 10];
long long s[maxn],f[maxn];
int tot ;
bool not_prime[maxn];
void init()
{
int i, j;
phi[1] = 1;
for ( int i = 2; i <= 4000000 ; i ++ )
{
if ( !not_prime[i] )
{
phi[i] = i - 1;
prime[++tot] = i;
}
{
for ( j = 1; j <= tot && i * prime[j] <= 4000000; j++ )
{
not_prime[i * prime[j]] = 1;
if ( i % prime[j] == 0 )
{
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
else
{
phi[i * prime[j]] = phi[i] * ( prime[j] - 1 );
}
}
}
//for ( i = 1; i <= 4000000; i++ ) sum[i] = ( sum[i - 1] + phi[i] ) % mod;
}
}
//预处理素数与欧拉函数值
int main()
{
init();
for (int i = 2 ; i < maxn ; i ++)
{
for (int j = 1 ; j * i <maxn ; j ++ )
{
f[j*i] += phi[i]*j;
}
}
for (int i = 2 ; i < maxn ; i ++)
{
s[i] = s[i-1] + f[i];
}
int n;
while (~scanf("%d",&n)&&n)
{
printf("%lld\n",s[n]);
}
}