Class 3
Class 3
Detailed Notes
Problem 1: GCD of Two Numbers
Solution:
class Solution {
public:
int gcd(int A, int B) {
if((max(A,B) % min(A,B)) == 0) {
return min(A,B);
}
return gcd((max(A,B) % min(A,B)), min(A,B));
}
};
Explanation:
Why it works:
Solution:
vector<int> Solution::sieve(int A) {
vector<int> vec(A + 1, 0);
vector<int> ans;
for(int i = 2; i <= A; i++) {
if(vec[i] == 0) {
vec[i] = 1;
ans.push_back(i);
for(int j = i; (long long) i * j <= (long long) A; j++) {
vec[i * j] = 1;
}
}
}
return ans;
}
Explanation:
The function generates all prime numbers up to a given number A using the
Sieve of Eratosthenes. It iteratively marks the multiples of each prime
number starting from 2. Numbers that remain unmarked after all multiples
have been accounted for are prime.
Why it works:
The Sieve of Eratosthenes is efficient for finding all primes smaller than N
because it minimizes the number of redundant checks for multiplicity by
ensuring each number is marked by its smallest prime divisor only once.
Time Complexity: O(n log(log(n))), where n is the number A. This is due to
the nature of the progression of marking multiples.
Solution:
class Solution {
public:
vector<int> AllPrimeFactors(int N) {
vector<int> ans;
int num = 2;
while(N > 1) {
if(N % num == 0) {
ans.push_back(num);
while(N % num == 0) {
N = N / num;
}
}
num++;
}
return ans;
}
};
Explanation:
Solution:
#include <cmath>
#include <iostream>
using namespace std;
int main() {
int N;
cin >> N;
int count = 0;
for (int i = 1; i <= ((int)sqrt(N)); i++) {
if (N % i == 0) {
count += 2; // Count both divisors i and N/i
}
}
if (((int)sqrt(N)) * ((int)sqrt(N)) == N) { // Check if N is a perfect
square
count--; // Decrement count for a repeated factor at the square
root
}
cout << count;
return 0;
}
Explanation:
Each factor less than the square root has a corresponding factor greater
than the square root. This approach effectively reduces the number of
necessary checks to about the square root of N, making it much more
efficient than checking up to N.
Solution:
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int Q;
cin >> Q;
vector<int> factors(10000, 0); // Precomputing smallest factors up to
9999
for (int i = 2; i < 10000; i++) {
if (factors[i] == 0) { // i is prime
for (int j = i; i * j < 10000; j++) {
if (factors[i * j] == 0) factors[i * j] = i;
}
}
}
while (Q--) {
int temp, ans = 1;
cin >> temp;
int original = temp;
while (temp > 1) {
int smallestFactor = factors[temp];
int count = 0;
while (temp % smallestFactor == 0) {
temp /= smallestFactor;
count++;
}
ans *= (count + 1);
}
cout << ans << " ";
}
return 0;
}
Explanation:
This program first precomputes the smallest prime factor for each number
up to 9999. For each query, it repeatedly divides the number by its smallest
prime factor (found in the precomputed list) until all factors are extracted,
counting the occurrences of each prime factor. The total number of factors
is then the product of (count of each prime factor + 1) for each unique
prime factor.
Why it works:
Space Complexity: O(1), ignoring the storage for the smallest prime factors
and the input storage, as no additional significant space is used in the
calculation.