您的位置:首页 > 其它

【51Nod 1188】最大公约数之和2

2016-07-06 19:46 405 查看

Description

给出一个数N,输出小于等于N的所有数,两两之间的最大公约数之和。

G=∑i<Ni=1∑j≤Nj=i+1gcd(i,j)

相当于计算这段程序(程序中的gcd(i,j)表示i与j的最大公约数):

G=0;

for(i=1;i

Solution

最大公约数和很像啦。这只是加强版而已。

范围变小了,用线性筛一下欧拉函数,然后找出所有包含此因数的且在范围内的数,然后统计答案。

用一个前缀和函数就好了。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=5000007;
typedef long long ll;
int i,j,k,l,t,n,m,q;
int phi[maxn],p[maxn];
bool bz[maxn];
ll ans,a[maxn];
int main(){
phi[1]=1;
fo(i,2,5000000){
if(!bz[i])p[++p[0]]=i,phi[i]=i-1;
fo(j,1,p[0]){
t=p[j]*i;if(t>maxn)break;bz[t]=1;
if(!(i%p[j])){phi[t]=phi[i]*p[j];break;}
phi[t]=phi[i]*(p[j]-1);
}
}
fo(i,2,maxn)fo(j,1,maxn/i)a[i*j]+=phi[i]*j;
fo(i,1,maxn)a[i]+=a[i-1];
for(scanf("%d",&q);q;q--){
scanf("%d",&n);
printf("%lld\n",a
);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: