Given an integer N, the task is to count the values of K ( where 1 ? K? N ), such that 1< GCD(K, N) < K.
Examples:
Input: N = 10
Output: 3
Explanation: The values of K which satisfies the given conditions are:
- K = 4, gcd(4, 10) = 2
- K = 6, gcd(6, 10) = 2
- K = 8, gcd(8, 10) = 2
Input: N = 15
Output: 4
Explanation: The values of K which satisfies the given conditions are:
- K = 6, gcd(6, 15) = 3
- K = 9, gcd(9, 15) = 3
- K = 10, gcd(10, 15) = 5
- K = 12, gcd(12, 15) = 3
Naive Approach: The simplest approach is to iterate over the range [1, N], and check for each number, whether it satisfies the given condition or not. Finally, print the count of such numbers.
Time Complexity: O(N*log(N))
Auxiliary Space: O(1)
Efficient Approach: The idea is to find all the numbers in the range [1, N], for which gcd(K, N) = 1 and gcd(K, N) = K and then finally remove all these numbers from N to get the final answer. Follow the steps below to solve the problem:
- Store all the prime factors of N using Sieve of Eratosthenes.
- Store the count of all the numbers in the range [1, N] for which gcd(N, K) = K in a variable count1.
- Store the count of all the numbers in the range [1, N] for which gcd(N, K) = 1 using Euler's Totient Function in a variable count2.
- Remove these numbers from N, by updating ans to N - (count1 + count2).
- Print the value of ans as the result.
Below is the implementation of the above approach:
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Store the all prime numbers
// using Sieve of Eratosthenes
const int MAXN = 100001;
vector<int> spf;
// Function to fill the prime numbers
// using Sieve of Eratosthenes
void sieve()
{
// Create a boolean array and
// initialize all entries it as 0
int p[MAXN + 1] = { 0 };
p[2] = 1;
for (long long int i = 3; i < MAXN; i += 2) {
p[i] = 1;
}
// Push the first prime number
spf.push_back(2);
for (long long i = 3; i < MAXN; i += 2) {
// If the current number is prime
if (p[i]) {
// Store the prime numbers
// in spf which is prime
spf.push_back(i);
// Mark all its multiples as false
for (long long int j = i * i; j < MAXN;
j += 2 * i)
p[j] = 0;
}
}
}
// Function to count the values of K where
// 1?K?N such that 1< gcd(K, N) < K
void countK(int N)
{
// Precalculate prime numbers
sieve();
int N1 = N;
// Store the smallest prime number
int div = spf[0];
int index = 1, C = 0;
// Store the count of those numbers in the
// range [1, N] for which gcd(N, K) = K
int count1 = 1;
// Store the count of those numbers from
// the range [1, N] such that gcd(N, K) = 1
float count2 = N;
// Iterate through all prime factors of N
while (div * div <= N) {
if (N % div == 0) {
C = 0;
while (N % div == 0) {
N /= div;
C++;
}
count1 = count1 * (C + 1);
// count2 is determined by
// Euler's Totient Function
count2 *= (1.0 - (1.0 / (float)div));
}
div = spf[index];
index++;
}
if (N != 1) {
count1 *= 2;
count2 = count2 * (1.0 - (1.0 / (float)N));
}
int ans = N1 - count1 - count2;
// Add 1 to result as 1 is contributed
// twice due to count1 and count2
ans = ans + 1;
// Print the result
cout << ans;
return;
}
// Driver Code
int main()
{
// Given Input
int N = 10;
// Function Call
countK(N);
return 0;
}
// Java code to implement the approach
import java.util.ArrayList;
class GFG {
// Store the all prime numbers
// using Sieve of Eratosthenes
private static final int MAXN = 100001;
private static ArrayList<Integer> spf
= new ArrayList<>();
// Function to fill the prime numbers
// using Sieve of Eratosthenes
private static void sieve()
{
// Create a boolean array and
// initialize all entries it as 0
int[] p = new int[MAXN + 1];
p[2] = 1;
for (long i = 3; i < MAXN; i += 2) {
p[(int)i] = 1;
}
// Push the first prime number
spf.add(2);
for (long i = 3; i < MAXN; i += 2) {
// If the current number is prime
if (p[(int)i] == 1) {
// Store the prime numbers
// in spf which is prime
spf.add((int)i);
// Mark all its multiples as false
for (long j = i * i; j < MAXN; j += 2 * i)
p[(int)j] = 0;
}
}
}
// Function to count the values of K where
// 1 <= K <= N such that 1< gcd(K, N) < K
private static void countK(int N)
{
// Precalculate prime numbers
sieve();
int N1 = N;
// Store the smallest prime number
int div = spf.get(0);
int index = 1, C = 0;
// Store the count of those numbers in the
// range [1, N] for which gcd(N, K) = K
int count1 = 1;
// Store the count of those numbers from
// the range [1, N] such that gcd(N, K) = 1
double count2 = N;
// Iterate through all prime factors of N
while (div * div <= N) {
if (N % div == 0) {
C = 0;
while (N % div == 0) {
N /= div;
C++;
}
count1 = count1 * (C + 1);
// count2 is determined by
// Euler's Totient Function
count2 *= (1.0 - (1.0 / (double)div));
}
div = spf.get(index);
index++;
}
if (N != 1) {
count1 *= 2;
count2 = count2 * (1.0 - (1.0 / (double)N));
}
int ans = N1 - count1 - (int)count2;
// Add 1 to result as 1 is contributed
// twice due to count1 and count2
ans = ans + 1;
// Print the result
System.out.println(ans);
return;
}
// Driver Code
public static void main(String[] args)
{
int N = 10;
// Function call
countK(N);
}
}
// This code is contributed by phasing17
# Python3 program for the above approach
# Store the all prime numbers
# using Sieve of Eratosthenes
MAXN = 100001
spf = []
# Function to fill the prime numbers
# using Sieve of Eratosthenes
def sieve():
global MAXN
# Create a boolean array and
# initialize all entries it as 0
p = [0] * (MAXN + 1)
p[2] = 1
for i in range(3, MAXN, 2):
p[i] = 1
# Push the first prime number
spf.append(2)
for i in range(3, MAXN, 2):
# If the current number is prime
if (p[i]):
# Store the prime numbers
# in spf which is prime
spf.append(i)
# Mark all its multiples as false
for j in range(i * i, MAXN, 2 * i):
p[j] = 0
# Function to count the values of K where
# 1?K?N such that 1< gcd(K, N) < K
def countK(N):
# Precalculate prime numbers
sieve()
N1 = N
# Store the smallest prime number
div = spf[0]
index, C = 1, 0
# Store the count of those numbers in the
# range [1, N] for which gcd(N, K) = K
count1 = 1
# Store the count of those numbers from
# the range [1, N] such that gcd(N, K) = 1
count2 = N
# Iterate through all prime factors of N
while (div * div <= N):
if (N % div == 0):
C = 0
while (N % div == 0):
N //= div
C += 1
count1 = count1 * (C + 1)
# count2 is determined by
# Euler's Totient Function
count2 *= (1.0 - (1.0 / div))
div = spf[index]
index += 1
if (N != 1):
count1 *= 2
count2 = count2 * (1.0 - (1.0 / N))
ans = N1 - count1 - count2
# Add 1 to result as 1 is contributed
# twice due to count1 and count2
ans = ans + 1
# Print the result
print(int(ans))
# Driver Code
if __name__ == '__main__':
# Given Input
N = 10
# Function Call
countK(N)
# This code is contributed by mohit kumar 29
// C# code to implement the approach
using System;
using System.Collections.Generic;
class GFG
{
// Store the all prime numbers
// using Sieve of Eratosthenes
private const int MAXN = 100001;
private static List<int> spf = new List<int>();
// Function to fill the prime numbers
// using Sieve of Eratosthenes
private static void sieve()
{
// Create a boolean array and
// initialize all entries it as 0
int[] p = new int[MAXN + 1];
p[2] = 1;
for (long i = 3; i < MAXN; i += 2) {
p[i] = 1;
}
// Push the first prime number
spf.Add(2);
for (long i = 3; i < MAXN; i += 2) {
// If the current number is prime
if (p[i] == 1) {
// Store the prime numbers
// in spf which is prime
spf.Add((int)i);
// Mark all its multiples as false
for (long j = i * i; j < MAXN; j += 2 * i)
p[j] = 0;
}
}
}
// Function to count the values of K where
// 1?K?N such that 1< gcd(K, N) < K
private static void countK(int N)
{
// Precalculate prime numbers
sieve();
int N1 = N;
// Store the smallest prime number
int div = spf[0];
int index = 1, C = 0;
// Store the count of those numbers in the
// range [1, N] for which gcd(N, K) = K
int count1 = 1;
// Store the count of those numbers from
// the range [1, N] such that gcd(N, K) = 1
double count2 = N;
// Iterate through all prime factors of N
while (div * div <= N) {
if (N % div == 0) {
C = 0;
while (N % div == 0) {
N /= div;
C++;
}
count1 = count1 * (C + 1);
// count2 is determined by
// Euler's Totient Function
count2 *= (1.0 - (1.0 / (double)div));
}
div = spf[index];
index++;
}
if (N != 1) {
count1 *= 2;
count2 = count2 * (1.0 - (1.0 / (double)N));
}
int ans = N1 - count1 - (int)count2;
// Add 1 to result as 1 is contributed
// twice due to count1 and count2
ans = ans + 1;
// Print the result
Console.WriteLine(ans);
return;
}
// Driver Code
static void Main(string[] args)
{
int N = 10;
// Function call
countK(N);
}
}
// This code is contributed by phasing17
<script>
// Javascript program for the above approach
// Store the all prime numbers
// using Sieve of Eratosthenes
var MAXN = 100001;
var spf = [];
// Function to fill the prime numbers
// using Sieve of Eratosthenes
function sieve()
{
// Create a boolean array and
// initialize all entries it as 0
var p = Array(MAXN + 1).fill(0);
p[2] = 1;
for (var i = 3; i < MAXN; i += 2) {
p[i] = 1;
}
// Push the first prime number
spf.push(2);
for (var i = 3; i < MAXN; i += 2) {
// If the current number is prime
if (p[i]) {
// Store the prime numbers
// in spf which is prime
spf.push(i);
// Mark all its multiples as false
for (var j = i * i; j < MAXN;
j += 2 * i)
p[j] = 0;
}
}
}
// Function to count the values of K where
// 1?K?N such that 1< gcd(K, N) < K
function countK(N)
{
// Precalculate prime numbers
sieve();
var N1 = N;
// Store the smallest prime number
var div = spf[0];
var index = 1, C = 0;
// Store the count of those numbers in the
// range [1, N] for which gcd(N, K) = K
var count1 = 1;
// Store the count of those numbers from
// the range [1, N] such that gcd(N, K) = 1
var count2 = N;
// Iterate through all prime factors of N
while (div * div <= N) {
if (N % div == 0) {
C = 0;
while (N % div == 0) {
N /= div;
C++;
}
count1 = count1 * (C + 1);
// count2 is determined by
// Euler's Totient Function
count2 *= (1.0 - (1.0 / div));
}
div = spf[index];
index++;
}
if (N != 1) {
count1 *= 2;
count2 = count2 * (1.0 - (1.0 / N));
}
var ans = N1 - count1 - count2;
// Add 1 to result as 1 is contributed
// twice due to count1 and count2
ans = ans + 1;
// Print the result
document.write(ans);
return;
}
// Driver Code
// Given Input
var N = 10;
// Function Call
countK(N);
// This code is contributed by rutvik_56.
</script>
Output:
3
Time Complexity: O(N*log(log(N)))
Auxiliary Space: O(N)