UVA 11426 GCD - Extreme (II) (欧拉函数)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Problem J
GCD Extreme (II)
Input: Standard Input
Output: Standard Output
Given the value of N, you will have to find the value of G. The definition of G is given below:
Here GCD(i,j) means the greatest common divisor of integer i and integer j.
For those who have trouble understanding summation notation, the meaning of G is given in the following code:
G=0; for(i=1;i<N;i++) for(j=i+1;j<=N;j++) { G+=gcd(i,j); } /*Here gcd() is a function that finds the greatest common divisor of the two input numbers*/ |
Input
The input file contains at most 100 lines of inputs. Each line contains an integer N (1<N<4000001). The meaning of N is given in the problem statement. Input is terminated by a line containing a single zero.
Output
For each line of input produce one line of output. This line contains the value of G for the corresponding N. The value of G will fit in a 64-bit signed integer.
Sample Input Output for Sample Input
10 100 200000 0
|
67 13015 143295493160
|
Problemsetter: Shahriar Manzoor
Special Thanks: SyedMonowarHossain
设dp[i]=gcd(1,i)+gcd(2,i)+……+gcd(i-1,i);
则ans[n]=dp[2]+dp[3]+……+dp[n].
由此问题已经转化成如何求dp[i]了,即需要求1到i-1所有数与i的gcd的和。
设k为满足gcd(x,i)=j且x<i的正整数的个数,则dp[i]=∑j*k;
同时,由于gcd(x,i)=j等价于gcd(x/j,i/j)=1,也就是phi[i/j];
接下来反过来求,那就不需要分解素因子了
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 typedef long long ll; 5 const int maxn=4000010; 6 int phi[maxn]; 7 ll dp[maxn+1]; 8 ll ans[maxn+1]; 9 void phi_table() 10 { 11 phi[1]=1; 12 for(int i=2;i<maxn;i++) 13 { 14 if(!phi[i]) 15 { 16 for(int j=i;j<maxn;j+=i) 17 { 18 if(!phi[j])phi[j]=j; 19 phi[j]=phi[j]/i*(i-1); 20 } 21 } 22 } 23 } 24 int main() 25 { 26 ios::sync_with_stdio(false); 27 phi_table(); 28 for(int i=1;i<maxn;i++) 29 { 30 for(int j=i*2;j<maxn;j+=i)dp[j]+=(long long)i*(long long)phi[j/i]; 31 } 32 ans[2]=dp[2]; 33 for(int i=3;i<maxn;i++)ans[i]=ans[i-1]+dp[i]; 34 int n; 35 while(cin>>n&&n) 36 { 37 cout<<ans[n]<<endl; 38 } 39 return 0; 40 }