-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtotient.cpp
65 lines (64 loc) · 1.15 KB
/
totient.cpp
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
63
64
65
#include <vector>
#include <cmath>
long long totient(long long a, std::vector<long long> &primes){
//if you have used sieve to precompute primes
//sieve must go to primes larger than or equal to a
// (in case a is a prime)
//O(logn) complexity
long long output{};
for(int i{}; i < primes.size(); ++i){
int counter{};
while(a%primes[i] == 0){
a /= primes[i];
if(counter)
count *= primes[i];
else
counter = 1;
}
if(counter == 0)
continue;
if(output)
output *= counter*(primes[i]-1)
else
output = counter*(primes[i]-1);
}
return output;
}
long long totient(long long a) {
//O(sqrt(n)) complexity
long long output{};
long long counter{};
while(a%2 == 0){
a /= 2;
if(counter)
counter *= 2;
else
counter = 1;
}
if(counter != 0){
output = counter;
}
for(int i=3; i < (long long)std::sqrt(a); i += 2){
counter = 0;
while(a%i == 0){
a /= i;
if(counter)
counter *= i;
else
counter = 1;
}
if(counter == 0)
continue;
if(output)
output *= counter*(i-1);
else
output = counter * (i-1);
}
if(a != 1){
if(output)
output *= a-1;
else
output = a-1;
}
return output;
}