Concepts Used
Mathematics
Difficulty Level
Hard
Problem Statement (Simplified):
Calculate the sum for a given number n:
Solving Approach :
Bruteforce Approach:
1) We can use a double loop to count sum for a given value of
n, where a loop also occurs inside two loops to findgcd(i,j).
2) The Above approach use three loops to solve the given problem. So it takes a total ofO(n³)time complexity which is highly inefficient for given constraints, so we add some maths magic to it and solve it faster.
Efficient Approach:
1) Let
gcd(i,j) = d, where d can go from1ton. Ifgcd(i,j)isd,iandjcan be represented as some multiple ofd, leti=k*dandj=l*d, wherek<lbecausei2) Our summation equation is, from above step we can see it becomes,
=>
![]()
(i=k*dandj=l*d)=>
![]()
(gcd(i,j) = d)=>
k*l3) Now, we have one summation for one value of
dranging from1toN, internally we have(k*l)summation over all pairs wherel>kandgcd(l,k)=1. Total number of pairs such thatgcd(n,k)=1whereklies between1andncan be found by using Euler Totient Function. An arrayphiwill be maintained for such values.
4) Also we knowgcd(l,k) = gcd(l,l-k)wherel>kandl>l-k, so in above recieved equation we can change value ofktol-k, as they both will have samegcd(), sosum(k*l) = sum(l*(l-k))).
5) We can make it further easy, assum(kl) = sum(which is also equal to
because we still need to find summation over
gcd(l,k)=1, where `k
6) Now we have onlylas variable to cound ranging from2to()anddlies in range1ton, which can be find inO()time for a given value ofn.
7) However we can calculate for all n = 2 to 2000000 using the below pseudocode:
Calculate phi() for all values between 1 to max range of numbers.
phi(n) returns the total number of values from 1 to n which have gcd() with n as 1.
Calculate (l*l*phi(l))/2 for all values of 2 to n with double summation as asked in the problem.
8) Note: Don’t forget to take modulo to avoid overflow.
Example
- Lets assume
Nto be10, thephitable for it would be:
| N | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| Value | 1 | 1 | 2 | 2 | 4 | 2 | 7 | 2 | 6 | 4 |
Where, phi(8) will be
2because,3and5both havegcd()1with8.Now , we have found the value of phi(k).
We find sunmmation of all values from
1to10with derived formula.Hence resultant array would be:
| N | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| Value | 0 | 2 | 11 | 29 | 79 | 126 | 273 | 419 | 671 | 923 |
- Hence, gcd sum of
10will be923.
Solutions
#include <stdio.h>
#define ll long long
#define N 1000000007
#define maxn 2000001
ll phi[maxn];
ll res[maxn];
void pre()
{
ll i,j;
for(i=1;i<maxn;i++)
phi[i] = i;
for(i=2;i<maxn;i++)
{
if(phi[i] == i)
{
for(j=i;j<maxn;j=j+i)
{
phi[j] = (phi[j]/i)*(i-1);
}
}
}
for(i=2;i<maxn;i++)
for(j=i;j<maxn;j=j+i)
res[j] = (res[j] + (((i*i)%N)*((phi[i]*500000004)%N))%N)%N;
for(i=2;i<maxn;i++)
res[i] = (res[i] + res[i-1])%N;
}
int main() {
pre();
int test;
scanf("%d",&test);
while(test--){
int n;
scanf("%d",&n);
ll ans = res[n];
ans = (ans+N)%N;
printf("%d\n",ans);
}
}
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 1000000007
#define maxn 2000001
ll phi[maxn];
ll res[maxn];
void pre()
{
ll i,j;
for(i=1;i<maxn;i++)
phi[i] = i;
for(i=2;i<maxn;i++)
{
if(phi[i] == i)
{
for(j=i;j<maxn;j=j+i)
{
phi[j] = (phi[j]/i)*(i-1);
}
}
}
for(i=2;i<maxn;i++)
for(j=i;j<maxn;j=j+i)
res[j] = (res[j] + (((i*i)%N)*((phi[i]*500000004)%N))%N)%N;
for(i=2;i<maxn;i++)
res[i] = (res[i] + res[i-1])%N;
}
int main() {
pre();
int test;
cin>test;
int v[maxn] = {0};
int j=0;
while(test--){
int n;
cin>n;
ll ans = res[n];
ans = (ans+N)%N;
v[j++]=ans;
}
for(int i = 0;i<j;i++)
cout << v[i] << '\n';
}
import java.util.*;
import java.io.*;
public class Main {
static int N = 1000000007;
static int maxn = 2000001;
static long phi[] = new long[maxn];
static long res[] = new long[maxn];
static void pre()
{
int i,j;
for(i=1;i<maxn;i++)
phi[i] = i;
for(i=2;i<maxn;i++)
{
if(phi[i] == i)
{
for(j=i;j<maxn;j=j+i)
{
phi[j] = (phi[j]/i)*(i-1);
}
}
}
for(i=2;i<maxn;i++)
for(j=i;j<maxn;j=j+i)
res[j] = (res[j] + ((((long)i*i)%N)*((phi[i]*500000004)%N))%N)%N;
for(i=2;i<maxn;i++)
res[i] = (((res[i] + res[i-1])+N) %N)%N;
}
public static void main(String args[]) throws IOException {
pre();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int test = Integer.parseInt(br.readLine());
while(test--!=0){
int n = Integer.parseInt(br.readLine());
long ans = res[n];
ans = (ans+N)%N;
System.out.println(ans);
}
br.close();
}
}
[forminator_quiz id="847"]
This article tried to discuss Mathematics. Hope this blog helps you understand and solve the problem. To practice more problems on Mathematics you can check out .
