f(n)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 272 Accepted Submission(s): 169
Problem Description
This time I need you to calculate the f(n) . (3<=n<=1000000)
f(n)= Gcd(3)+Gcd(4)+…+Gcd(i)+…+Gcd(n).
Gcd(n)=gcd(C[n][1],C[n][2],……,C[n][n-1])
C[n][k] means the number of way to choose k things from n some things.
gcd(a,b) means the greatest common divisor of a and b.
f(n)= Gcd(3)+Gcd(4)+…+Gcd(i)+…+Gcd(n).
Gcd(n)=gcd(C[n][1],C[n][2],……,C[n][n-1])
C[n][k] means the number of way to choose k things from n some things.
gcd(a,b) means the greatest common divisor of a and b.
Input
There are several test case. For each test case:One integer n(3<=n<=1000000). The end of the in put file is EOF.
Output
For each test case:
The output consists of one line with one integer f(n).
The output consists of one line with one integer f(n).
Sample Input
3 26983
Sample Output
3 37556486这题要用到筛选素数法和拆分质因子AC代码+详解:/* Gcd(n)可以直接算出: 1,当n为质数(质数就是素数)时,Gcd(n)=n; 2,当n为某个质数k的q次方时(q>=2) Gcd(n)=k; 3,其它情况都为1。 */ #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<iomanip> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<string> #include<cstring> #include<map> #include<set> const int MAX=1000001; __int64 p[MAX]; __int64 f[MAX]; __int64 prime_max[MAX]; using namespace std; void init()//初始化 { __int64 i,j,count; memset(p,0,sizeof(p)); count=0; for(i=2;i<MAX;i++)//筛选1000000内中素数并且每个数都有属于自己最大素数 { if(!p[i]) { prime_max[count++]=i; for(j=i*i;j<MAX;j+=i) p[j]=1;//已经有最大素数 } } } __int64 eular(__int64 n) { __int64 i,k,count; count=0; for(i=0;prime_max[i]*prime_max[i]<=n;i++) { if(n%prime_max[i]==0)// { n/=prime_max[i]; while(n%prime_max[i]==0) n/=prime_max[i]; k=prime_max[i]; count+=1; } if(count>=2)//这里当count大于等于2表明该数有2个或2个以上质数(即素数)组成那么根据题意Gcd(n)就只能为1,因为两个质数的最大公约数是1 return 1; } if(n>1)//如果剩下的n就是质数 { count+=1;//先加上1 k=n; } if(count>=2)//如果count大于等于2那么也表明该数有2个或2个以上质数(即素数)组成那么根据题意Gcd(n)就只能为1 return 1; else return k;//否则n没有进入上诉循环,只能是单个素数所以返回自己 } int main() { __int64 n,m,i,j; init(); memset(f,0,sizeof(f)); for(i=3;i<MAX;i++) { if(p[i])//如果有存在最大素数 f[i]=f[i-1]+eular(i); else//否则自己就是素数 f[i]=f[i-1]+i; } while(cin>>n) cout<<f[n]<<endl; return 0; }