-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathP516.cpp
129 lines (117 loc) · 2.31 KB
/
P516.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>
#include <stdio.h>
#define PRIME_LEN 16400
class PrimeHandler {
bool primes[PRIME_LEN];
public:
void init() {
for(int i = 0; i < PRIME_LEN; ++i)
primes[i] = true;
// Sieve primes:
for(int i = 0; i*i < PRIME_LEN; ++i) {
if(!primes[i])
continue;
// Mark all uneven multiples as non-prime:
int basePrime = 1+2*(i+1);
for(int multiple = 3; true; multiple += 2) {
int notAPrime = basePrime*multiple;
int notAPrimeI = notAPrime/2-1;
if(notAPrimeI >= PRIME_LEN)
break;
primes[notAPrimeI] = false;
}
}
}
bool isPrime(long n) const {
if(n == 2)
return true;
if(n < 2 || (n%2==0))
return false;
return primes[n/2-1];
}
int nextPrime(int n) const {
int ni = n/2;
while(!primes[ni]) {
++ni;
}
return 1+(ni+1)*2;
}
int prevPrime(int n) const {
int ni = n/2-2;
while(!primes[ni])
--ni;
return 1+(ni+1)*2;
}
};
bool readInt(char *w, int &pos, int &a) {
a = 0;
char c;
while(isprint(c = w[pos++])) {
if(c >= '0' && c <= '9')
a = 10*a+(c-'0');
else if(a != 0)
return true;
}
return false;
}
int slowExp(int p, int e) {
int ret = 1;
for(int i = 0; i < e; ++i)
ret*=p;
return ret;
}
int main() {
// Compute prime numbers:
PrimeHandler ph;
ph.init();
int p, e;
char w[1000];
while(true) {
// Compute n:
gets(w);
int n = 1;
int pos = 0;
readInt(w, pos, p);
if(p == 0)
return 0;
while(true) {
bool go = readInt(w, pos, e);
n *= slowExp(p, e);
if(!go)
break;
readInt(w, pos, p);
}
// Subtract one:
//std::cerr << "For n=" << n << " outputting n-1 = " << (n-1) << std::endl;
--n;
// Output new value:
int prime = n % 2 == 0 ? n+1 : n;
prime = ph.nextPrime(prime);
bool first = true;
while(prime >= 3) {
int times = 0;
while(n % prime == 0) {
n /= prime;
++times;
}
if(times > 0) {
if(!first)
std::cout << " ";
first = false;
std::cout << prime << " " << times;
}
prime = ph.prevPrime(prime);
}
int times2 = 0;
while(n % 2 == 0) {
n /= 2;
++times2;
}
if(times2 > 0) {
if(!first)
std::cout << " ";
std::cout << 2 << " " << times2;
}
std::cout << std::endl;
}
}