题目链接: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; }