GCD

题目链接:https://vjudge.net/problem/UVA-11426

题目大意: 给出整数n∈[2,4000000],求解∑gcd(i,j),其中(i,j)满足1≤i<j≤n.

的确没有想到是欧拉函数,这怎么会想到欧拉函数呢?  又不是要我们求所有gcd为1的个数  那些gcd不为1的怎么办呢?  当时怎么就没想到呢  除过去不就变为1了吗  自己是真的菜。。。  

还是要多做题,把思维开阔起来!!!

思路在代码中  直接看代码:

/**
欧拉函数三个性质
是素数的话  欧拉函数值等于它本身-1
如果a是素数 b%a==0  则phi[b*a]=phi[b]*a
如果b%a!=0  则phi[b*a]=phi[b]*phi[a]
*/
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=4e6+50;
LL N;
LL phi[maxn],vis[maxn],p[maxn];//欧拉函数值  是否是素数  存素数
LL f[maxn],ans[maxn];
void Init()//求欧拉函数值
{
    phi[1]=1;
    int num=0;
    for(int i=2;i<maxn;i++)
    {
        if(!vis[i])//是素数
        {
            p[num++]=i;
            phi[i]=i-1;//素数的欧拉函数值就等于它的值-1
        }
        for(int j=0;j<num&&p[j]*i<maxn;j++)
        {
            vis[p[j]*i]=true;//肯定不是素数
            if(i%p[j]==0)
            {
                phi[i*p[j]]=p[j]*phi[i];
                break;
            }
            else phi[i*p[j]]=phi[i]*phi[p[j]];
        }
    }

//    for(int i=1;i<=10;i++) cout<<i<<":"<<phi[i]<<" ";
    return ;
}
/** 假设n等于4
(1,2) (2,3) (3,4)
(1,3) (2,4)
(1,4)

假设f[n]=(1,n)+(2,n)+···(n-1,n)
则 ans=f[2]+f[3]+···+f[n]  所以我们要求的就是f[n]

假设 gcd(1,n) gcd(2,n)  ···  gcd(n-1,n)中等于i的有si个
那么gcd(s1,n)=i  gcd(s2,n)=i  gcd(si,n)=i
则 gcd(s1/i,n/i)=1  gcd(s2/i,n/i)=1 gcd(si/i,n/i)=1
这岂不是转换成了 总个数phi[n/i]的情形了  所以f[n]=i*phi[n/i]

*/
void solve()//存f[n]
{
    phi[1]=0;
    for(int i=1;i<maxn;i++)//遍历i的值  同时得到f[n]的部分值
    {
        for(int j=i;j<maxn;j+=i)//遍历n的值
        {
            f[j]+=i*phi[j/i];
        }
    }
    for(int i=2;i<maxn;i++) ans[i]=ans[i-1]+f[i];
    return ;
}
int main()
{
    Init();
    solve();
    //while(scanf("%lld",&N)!=EOF)
    while(cin>>N)
    {
        if(N==0) break;
        cout<<ans[N]<<endl;
        //printf("%lld
",ans[N]);
    }
    return 0;
}
当初的梦想实现了吗,事到如今只好放弃吗~
原文地址:https://www.cnblogs.com/caijiaming/p/10645488.html