您的位置:首页 > 其它

fzu1969 GCD Extreme 类似于uva10561

2014-09-09 16:58 190 查看
Description

Given the value of N, you will have to find the value of G. The meaning of G is given in the following code

G=0;

for(i=1;i<N;i++)

for(j=i+1;j<=N;j++)


G+=gcd(i,j);


/*Here gcd() is a function that finds the greatest common divisor of the two input numbers*/

Input

The input file contains at most 20000 lines of inputs. Each line contains an integer N (1<N <1000001). The meaning of N is given in the problem statement. Input is terminated by a line containing a single zero.

Output

For each line of input produce one line of output. This line contains the value of G for the corresponding N. The value of G will fit in a 64-bit signed integer.

Sample Input

10 100 200000 0

Sample Output

67 13015 143295493160

Source

Contest for 2010 lecture II

题意:给出数字n,求对于所有满足1<= i < j <= n 的所有数对,(i,j)所对应的gcd(i,j)之和。

思路:设f(n) = gcd(1,n)+gcd(2,n)+gcd(3,n)+。。。+gcd(n-1,n)。则所求答案s(n)=f(2)+f(3)+f(4)+。。。+f(n)。

注意到所有的gcd(x,n)的值都是n的约数,所以可以按照这个约数来进行分类。用g(n,i)来表示满足gcd(x,n)=i且x<n的正整数x的个数。则f(n)={i×g(n,i)|i为n的约数}。注意,g(n,i)=phi(n,i)。

如果对于每个n都枚举i,按照数据范围来看肯定会超时,我们不如反着来,先枚举i,再找i的倍数n。这样时间复杂度会进一步减少。

/*
* Author:  Joshua
* Created Time:  2014年09月07日 星期日 19时26分30秒
* File Name: fzu1969.cpp
*/
#include<cstdio>
#include<cstring>
typedef long long LL;
#define maxn 1000005
int phi[maxn],a[maxn],f[maxn];
LL s[maxn];
bool p[maxn];
int tot=0;

void pri()
{
memset(p,1,sizeof(p));
for (int i=2;i<maxn;++i)
if (p[i])
{
for (int j=i<<1;j<maxn;j+=i)
p[j]=false;
}
for (int i=2;i<maxn;++i)
if (p[i]) a[++tot]=i;
}

void phi_table()
{
for (int i=2;i<maxn;++i)
{
phi[i]=i;
int temp=i;
for (int j=1;j<=tot;++j)
{
if (temp==1) break;
if (p[temp])
{
phi[i]/=temp;
phi[i]*=temp-1;
break;
}
if (temp % a[j] == 0)
{
phi[i]/=a[j];
phi[i]*=a[j]-1;
while (temp%a[j]==0) temp/=a[j];
}
}
}
}

void solve()
{
pri();
phi_table();
for (int i=1;i<maxn;++i)
for (int j=i;j<maxn;j+=i)
f[j]+=i*phi[j/i];
for (int i=1;i<maxn;++i)
s[i]+=s[i-1]+f[i];
}

int main()
{
int n;
solve();
while (scanf("%d",&n) && n)
printf("%lld\n",s
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: