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.
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).
Sample Input
3 26983
Sample Output
3 37556486
思路:
看着这个题觉得是找规律,打了个表没看出规律来,看了别人的博客才知道的。
规律为:
(1)如果n有多个素因子,那么Gcd=1;
(2)如果n只有一个素因子,那么Gcd=该素因子。(比如16=2^4,只有一个素因子2所以Gcd=2。而11本身是素数也只有一个素因子,所以gcd=11就是它本身)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
ll Gcd[1000100];
int main()
{
// for(int j=1;j<=45;j++)//打表
// {
// int n=j;
// ll ans=n;
// ll tt=n;
// for(int i=2;i<n;i++)
// {
// tt=tt*(n-i+1)/i;
// ans=__gcd(ans,tt);
// }
// printf("%d %d\n",j,ans);
// }
memset(Gcd,0,sizeof(Gcd));
for(int i=2;i<=1000000;i++)
{
if(!Gcd[i])
{
Gcd[i]=i;
for(int j=i*2;j<=1000000;j+=i)
{
if(!Gcd[j])//j不是素数,现在找到他的第一个因子是i
Gcd[j]=i;
else//之前已经找到了他的一个因子,现在又找到一个,说明不止一个因子
Gcd[j]=1;
}
}
}
for(int i=4;i<=1000000;i++)
{
Gcd[i]+=Gcd[i-1];
}
int n;
while(~scanf("%d",&n))
{
printf("%lld\n",Gcd[n]);
}
return 0;
}