-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproblem029.cpp
More file actions
62 lines (59 loc) · 1.85 KB
/
problem029.cpp
File metadata and controls
62 lines (59 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "lib/mathutils.h"
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
int distinctPowers(int baseUpper, int expUpper)
{
// All perfect powers of the same degree have an equal amount of duplicates
// in their raised powers while numbers that are not perfect powers have
// distinct powers. The highest perfect power will be a power of 2 so
// counting duplicates for powers of 2 is enough to cover all bases.
int len = log2(baseUpper) + 1;
std::vector<int> frequency(len);
std::vector<int> duplicates(len);
int sqrtBaseUpper = sqrt(baseUpper);
std::vector<bool> skip(sqrtBaseUpper + 1);
// Computes the size of each perfect power group.
for (int i = 2; i <= sqrtBaseUpper; ++i) {
if (skip[i]) {
continue;
}
int power = i * i;
int degree = 2;
while (power <= baseUpper) {
if (power <= sqrtBaseUpper) {
skip[power] = true;
}
++frequency[degree];
++degree;
power *= i;
}
}
// Counts duplicates for each group.
for (int i = 2; i < len; ++i) {
std::vector<bool> discovered(expUpper + 1);
for (int j = 1; j < i; ++j) {
int inc = lcm(i, j) / i;
int pos = std::max(2, inc);
int limit = expUpper * j / i;
while (pos <= limit) {
if (!discovered[pos]) {
++duplicates[i];
discovered[pos] = true;
}
pos += inc;
}
}
}
int duplicateCount = 0;
for (int i = 2; i < len; ++i) {
duplicateCount += frequency[i] * duplicates[i];
}
return (baseUpper - 1) * (expUpper - 1) - duplicateCount;
}
int main()
{
std::cout << "Answer: " << distinctPowers(100, 100) << '\n';
return 0;
}