|
| 1 | +# LOJ 1443 - Printing Divisors |
| 2 | + |
| 3 | +## Summary |
| 4 | +Print the divisors of a given number N in an order such that when two consecutive divisors are divided, the result is a prime number. |
| 5 | + |
| 6 | +## Prerequisite |
| 7 | +Prime factorization: https://cp-algorithms.com/algebra/factorization.html |
| 8 | +(For solving this problem the basic O( $\sqrt{N}$ ) algorithm will suffice) |
| 9 | + |
| 10 | +## Solution |
| 11 | +Say, N = $2^4$ * $3^2$ * $5^2$ |
| 12 | + |
| 13 | +M = $2^4$ * $3^0$ * $5^0$ |
| 14 | + |
| 15 | +Clearly M is a divisor of N and writing all the divisors of M is pretty easy:- |
| 16 | + |
| 17 | + |
| 18 | +1, $2^1$, $2^2$, $2^3$, $2^4$. |
| 19 | + |
| 20 | +Now, let's raise the power of 3 by 1. M = $2^4$ * $3^1$ * $5^0$ and the divisors of M we get are: |
| 21 | + |
| 22 | +1, $2^1$, $2^2$, $2^3$, $2^4$, |
| 23 | + |
| 24 | +$2^4$ * $3^1$, $2^3$ * $3^1$, $2^2$ * $3^1$, $2^1$ * $3^1$, 1 * 3. |
| 25 | + |
| 26 | +Raising the power of 3 again by 1. M = $2^4$ * $3^2$ * $5^0$ and the divisors of M now are: |
| 27 | + |
| 28 | +1, $2^1$, $2^2$, $2^3$, $2^4$, |
| 29 | + |
| 30 | +$2^4$ * $3^1$, $2^3$ * $3^1$, $2^2$ * $3^1$, $2^1$ * $3^1$, 1 * 3, |
| 31 | + |
| 32 | +1 * $3^2$, $2^1$ * $3^2$, $2^2$ * $3^2$, $2^3$ * $3^2$, $2^4$ * $3^2$. |
| 33 | + |
| 34 | +Raising the power of 5 by 1. M = $2^4$ * $3^2$ * $5^1$ and the list of the divisors of M is: |
| 35 | + |
| 36 | +1, $2^1$, $2^2$, $2^3$, $2^4$, $2^4$ * $3^1$, $2^3$ * $3^1$, $2^2$ * $3^1$, $2^1$ * $3^1$, 1 * 3, 1 * $3^2$, $2^1$ * $3^2$, $2^2$ * $3^2$, $2^3$ * $3^2$, $2^4$ * $3^2$, |
| 37 | + |
| 38 | +$2^4$ * $3^2$ * $5^1$, $2^3$ * $3^2$ * $5^1$, $2^2$ * $3^2$ * $5^1$, $2^1$ * $3^2$ * $5^1$, $3^2$ * $5^1$, $3^1$ * $5^1$, 1 * $5^1$. |
| 39 | + |
| 40 | +Now, for M = N = $2^4$ * $3^2$ * $5^2$ we get: |
| 41 | + |
| 42 | +1, $2^1$, $2^2$, $2^3$, $2^4$, $2^4$ * $3^1$, $2^3$ * $3^1$, $2^2$ * $3^1$, $2^1$ * $3^1$, 1 * 3, 1 * $3^2$, $2^1$ * $3^2$, $2^2$ * $3^2$, $2^3$ * $3^2$, $2^4$ * $3^2$, |
| 43 | + |
| 44 | +$2^4$ * $3^2$ * $5^1$, $2^3$ * $3^2$ * $5^1$, $2^2$ * $3^2$ * $5^1$, $2^1$ * $3^2$ * $5^1$, $3^2$ * $5^1$, $3^1$ * $5^1$, 1 * $5^1$, |
| 45 | + |
| 46 | +1 * $5^2$, $3^1$ * $5^2$, $3^2$ * $5^2$, $2^1$ * $3^2$ * $5^2$, $2^2$ * $3^2$ * $5^2$, $2^3$ * $3^2$ * $5^2$, $2^4$ * $3^2$ * $5^2$. |
| 47 | + |
| 48 | +Done! |
| 49 | + |
| 50 | +When finding the divisors of a subset of prime numbers raised to specific powers, a pattern can be observed. After finding all the divisors of the initial subset, the power of a different prime number can be increased one by one and the previous divisors (excluding the new prime number) can be multiplied by it. The order in which the divisors are multiplied by the new prime number depends on whether the power is odd or even. If the power is odd, the divisors are multiplied starting from the back of the list, and if the power is even, the divisors are multiplied starting from the beginning of the list. This pattern can be used to construct a solution. So the answer can never be "**impossible**". |
| 51 | + |
| 52 | +## Complexity |
| 53 | +- Time Complexity: O(T * $\sqrt{N}$). |
| 54 | +- Memory Complexity: O( $\sqrt{N}$ ). |
| 55 | + |
| 56 | +## Code |
| 57 | + |
| 58 | +### C++ |
| 59 | + |
| 60 | +```cpp |
| 61 | +#include <bits/stdc++.h> |
| 62 | + |
| 63 | +using namespace std; |
| 64 | + |
| 65 | +typedef long long ll; |
| 66 | + |
| 67 | + |
| 68 | +int main(int argc, const char *argv[]) { |
| 69 | + |
| 70 | + // for fast IO |
| 71 | + ios_base::sync_with_stdio(false); |
| 72 | + cin.tie(nullptr); |
| 73 | + |
| 74 | + int t; |
| 75 | + cin >> t; |
| 76 | + |
| 77 | + for(int ts = 1; ts <= t; ++ts) { |
| 78 | + ll n; |
| 79 | + cin >> n; |
| 80 | + |
| 81 | + vector <ll> ans {1}; |
| 82 | + for(ll i = 2; i*i <= n; ++i) { |
| 83 | + int cnt = 0; |
| 84 | + while (n % i == 0) { |
| 85 | + cnt++; |
| 86 | + n /= i; |
| 87 | + } |
| 88 | + |
| 89 | + bool flag = false; // first backward iteration because of satisfying the contraint. For first prime number it doesn't matter. |
| 90 | + int x = i; |
| 91 | + int current_size = ans.size(); // size of the divisors list not containing the prime number i |
| 92 | + while (cnt > 0) { |
| 93 | + if (flag) { |
| 94 | + // forward iteration |
| 95 | + for(int i = 0; i < current_size; ++i) ans.push_back(ans[i] * x); |
| 96 | + } |
| 97 | + else { |
| 98 | + // backward iteration |
| 99 | + for(int i = current_size-1; i >= 0; --i) ans.push_back(ans[i] * x); |
| 100 | + } |
| 101 | + flag ^= true; |
| 102 | + x *= i; // raising to the next power of that prime number |
| 103 | + cnt--; |
| 104 | + } |
| 105 | + } |
| 106 | + |
| 107 | + if (n > 1) { |
| 108 | + // a single prime factor greater than square root of that number |
| 109 | + for(int i = ans.size()-1; i >= 0; --i) ans.push_back(n * ans[i]); |
| 110 | + } |
| 111 | + |
| 112 | + cout << "Case " << ts << ":\n"; |
| 113 | + for(ll x : ans) { |
| 114 | + cout << x << ' '; |
| 115 | + } |
| 116 | + cout << '\n'; |
| 117 | + } |
| 118 | + |
| 119 | + return 0; |
| 120 | +} |
| 121 | +``` |
0 commit comments