题意:求∑gcd(i, N) 1<=i <=N
思路:求出所有约数
欧拉函数
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 #define MAXN 10000 8 long long Div[MAXN],prime[MAXN],factor[MAXN],l[MAXN],p[MAXN]; 9 bool use[70000]; 10 long long n,m,top=0; 11 void make_prime() 12 { 13 memset(use,1,sizeof(use)); 14 use[1]=0; use[0]=0; 15 int i,j; 16 for(i=2;i<300;i++) 17 if(use[i]) 18 for(j=i*i;j<70000;j+=i) 19 use[j]=0; 20 j=0; 21 for(i=2;i<70000;i++) 22 if(use[i]) 23 prime[++j]=i; 24 m=j; 25 } 26 27 long long divide(long long x,long long p[],long long prime[]) 28 { 29 int i,j=0; 30 for(i=1;i<=m;i++) 31 { 32 if(x<prime[i]) break; 33 if(x%prime[i]!=0) continue; 34 p[++j]=prime[i]; 35 l[j]=0; 36 while(x%prime[i]==0) 37 { 38 x/=prime[i]; 39 l[j]++; 40 } 41 } 42 if(x!=1) 43 { 44 p[++j]=x; 45 l[j]=1; 46 } 47 return j; 48 } 49 void dfs(int t,long long x) 50 { 51 if(t==m+1) 52 { 53 factor[++top]=x; 54 return ; 55 } 56 dfs(t+1,x); 57 for(int i=1;i<=l[t];i++) 58 x=x*Div[t], dfs(t+1,x); 59 } 60 long long Euler(long long p[],long long m,long long n) 61 { 62 int i; 63 for(i=1;i<=m;i++) 64 n=n/p[i]*(p[i]-1); 65 return n; 66 } 67 void solve() 68 { 69 int i,m; 70 long long ans=0; 71 for(i=1;i<=top;i++) 72 { 73 m=divide(n/factor[i],p,Div); 74 ans+=factor[i]*Euler(p,m,n/factor[i]); 75 } 76 printf("%lld\n",ans); 77 } 78 int main() 79 { 80 int i,j; 81 make_prime(); 82 while(scanf("%lld",&n)!=EOF) 83 { 84 m=6935; 85 top=0; 86 m=divide(n,Div,prime); 87 dfs(1,1); 88 solve(); 89 } 90 return 0; 91 }