/**
* Notes from Week-2 Class of NSUPS Bootcamp S15
* Author: Nadman Ashraf Khan
*/
#include <bits/stdc++.h>
using namespace std;
/**
* List Number, and Sum of Factors/Divisors, and Primality Test in O(sqrt(n))
* ===============================================================================
*
* * Using factor pairs for O(sqrt(n)) computation of the problems
* - https://w...content-available-to-author-only...s.org/why-do-we-check-up-to-the-square-root-of-a-number-to-determine-if-that-number-is-prime/
* - https://w...content-available-to-author-only...s.org/introduction-to-primality-test-and-school-method/
* - https://w...content-available-to-author-only...s.org/count-divisors-n-on13/
*/
/*
36 = 1 * 36
= 2 * 18
= 3 * 12
= 4 * 9
= 6 * 6
Thus we can get all the divisors of 36 by iterating from 1 up to only 6, which is the
square-root of 36. This is true for all integers.
*/
/// Returns the list of divisors/factors of `n`.
vector<int> divisors(int n) {
vector<int> res;
/// Naive solution: O(n)
/// Uses trial division from 1 to n.
// for (int i = 1; i <= n; ++i) {
// if (n % i == 0) {
// res.push_back(i);
// }
// }
// ---
/// Better solution: O(sqrt(n))
/// Uses factor pairs
for (int i = 1; i * i <= n; ++i) {
if (n % i == 0) {
res.push_back(i);
/// Because `i == n / i` if `n` is a perfect square,
/// and not checking this will add a duplicate divisor
/// in the list.
if (n / i != i) {
res.push_back(n / i);
}
}
}
/// Only if the divisors need to be sorted
sort(res.begin(), res.end());
return res;
}
bool is_prime(int n) {
/// Naive solution: O(n)
/// Uses trial division from 2 to n-1.
// for (int i = 2; i < n; ++i) {
// if (n % i == 0) {
// return false;
// }
// }
// return true;
// ---
/// Better solution: O(sqrt(n))
/// Uses the fact that the smallest factor of n that is
/// greater than 1, if n is composite, is less than or equal to
/// the square-root of n.
// Do not write `i <= sqrt(n)`!!!
for (int i = 2; (i * i) <= n; ++i) {
if (n % i == 0) {
return false;
}
}
return true;
}
int num_divisors(int n) {
int res = 0;
for (int i = 1; i * i <= n; ++i) {
if (n % i == 0) {
res++;
if (n / i != i) {
res++;
}
}
}
return res;
}
int sum_divisors(int n) {
int res = 0;
for (int i = 1; i * i <= n; ++i) {
if (n % i == 0) {
res += i;
if (n / i != i) {
res += (n / i);
}
}
}
return res;
}
/**
* Introductory Modular Arithmetic
* ===============================
*
* * Properties of modular addition, subtraction, multiplication
* - https://u...content-available-to-author-only...o.guide/gold/modular?lang=cpp
* - https://w...content-available-to-author-only...s.org/modular-arithmetic/
* - https://e...content-available-to-author-only...a.org/wiki/Modular_arithmetic
*
* * Modulo of a big "stringified" integer using modular arithmetic properties
* - https://w...content-available-to-author-only...s.org/how-to-compute-mod-of-a-big-number/
*/
/// The remainder operator % does not behave like the
/// mathematical modulo (`mod`) operation for negative numbers.
/// For negative numbers, % gives a non-positive (negative or zero)
/// integer in the interval [-modulus+1, 0], but we need a non-negative
/// (positive or zero) integer in the interval [0, modulus-1].
/// This modulo function does that.
int modulo(int n, int m) {
{
/// 1st method
auto res = n % m;
if (res < 0) res += m;
return res;
}
{
/// 2nd method
auto res = ((n % m) + m) % m;
return res;
}
}
/*
modular addition:
(a + b) mod m == ((a mod m) + (b mod m)) mod m
modular subtraction:
(a - b) mod m == ((a mod m) - (b mod m)) mod m
modular multiplication:
(a * b) mod m == ((a mod m) * (b mod m)) mod m
*/
/// Example problem using modular arithmetic to compute a number that would otherwise overflow
const int mod = 1e9 + 7; // constant modulus; will be specified by the problem
long long modular_factorial(int n) {
long long factorial = 1;
for (long long i = 2; i <= n; ++i) {
factorial *= i;
factorial %= mod;
}
factorial %= mod;
return factorial;
}
/// `n` is too long to be represented as a 64-bit integer type (`long long`).
/// So use string to hold its value (e.g. "1234") and compute it modulo `m`
/// using the properties of modular arithmetic learned so far.
int string_modulo(string n, int m) {
{
/// 1st method: iterate from right to left
long long res = 0;
long long pv = 1; // place value
for (int i = n.size() - 1; i >= 0; --i) {
int digit = n[i] - '0'; // numeric value from ascii
res += (pv * digit) % m;
res %= m;
pv *= 10;
pv %= m;
}
return res;
}
{
/// 2nd method: iterate from left to right
long long res = 0;
for (auto c : n) {
int digit = c - '0'; // numeric value from ascii
res = (((res * 10) % m) + digit) % m;
}
return res;
}
}
int main() {
return 0;
}