给出一个数N,输出小于等于N的所有数,两两之间的最大公约数之和。
相当于计算这段程序(程序中的gcd(i,j)表示i与j的最大公约数):
G=0;
for(i=1;i<N;i++)
for(j=i+1;j<=N;j++)
{
G+=gcd(i,j);
}
Input
第1行:1个数T,表示后面用作输入测试的数的数量。(1 <= T <= 50000)
第2 - T + 1行:每行一个数N。(2 <= N <= 5000000)
Output
共T行,输出最大公约数之和。
Input示例
3
10
100
200000
Output示例
67
13015
相当于计算这段程序(程序中的gcd(i,j)表示i与j的最大公约数):
G=0;
for(i=1;i<N;i++)
for(j=i+1;j<=N;j++)
{
G+=gcd(i,j);
}
Input
第1行:1个数T,表示后面用作输入测试的数的数量。(1 <= T <= 50000)
第2 - T + 1行:每行一个数N。(2 <= N <= 5000000)
Output
共T行,输出最大公约数之和。
Input示例
3
10
100
200000
Output示例
67
13015
143295493160
筛欧拉数,gcd(x,y)=n,则 gcd(x/n,y/n)=1 ,所以找到互素的个数之后在乘以n就是 gcd(x,y);
#include<stack>
#include<queue>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<map>
#include<iostream>
#include<string.h>
#include<algorithm>
#define maxn 5000005
#define maxm 10000005
#define MAXN 100005
#define MAXM 10005
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
//ll mindiv[maxn],phi[maxn],sum[maxn];
ll sum[maxn];
//void getphi(){
// for(ll i=1;i<maxn;i++)mindiv[i]=i;
// for(ll i=2;i*i<maxn;i++){
// if(mindiv[i]==i){
// for(ll j=i*i;j<maxn;j+=i)
// mindiv[j]=i;
// }
// }
// phi[1]=1;
// for(ll i=2;i<maxn;i++){
// phi[i]=phi[i/mindiv[i]];
// if((i/mindiv[i])%mindiv[i]==0){
// phi[i]*=mindiv[i];
// }else
// phi[i]*=mindiv[i]-1;
// }
//}
bool check[maxn+10];
int prime[maxn+10];
int tot;
int phi[maxn];
//void getphi(){
// mem(phi,0);
// phi[1]=1;
// for(int i=2;i<=maxn;i++){
// if(!phi[i]){
// for(int j=i;j<=maxn;j+=i){
// if(!phi[j])phi[j]=j;
// phi[j]=phi[j]/i*(i-1);
// }
// }
// }
//}
void getphi(){
mem(check,false);
phi[1]=1;tot=0;
for(int i=2;i<maxn;i++){
if(!check[i]){prime[tot++]=i;phi[i]=i-1;}
for(int j=0;j<tot;j++){
if(i*prime[j]>maxn)break;
check[i*prime[j]]=true;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];break;
}
else
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
void s(){
getphi();
for(ll i=1;i<maxn;i++){
for(ll j=2;j<maxn;j++){
if(i*j<maxn)
sum[i*j]+=phi[j]*i;
else break;
}
}
for(int i=1;i<maxn;i++){
sum[i]+=sum[i-1];
}
}
int main(){
s();
int t;scanf("%d",&t);
while(t--){
ll n;scanf("%lld",&n);
printf("%lld\n",sum[n]);
}
return 0;
}