相当于计算这段程序(程序中的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 ",sum[n]); } return 0; }