-
Notifications
You must be signed in to change notification settings - Fork 166
/
totient-until-the-end.cpp
122 lines (105 loc) · 1.89 KB
/
totient-until-the-end.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
//totient-until-the-end.cpp
//Totient Until The End
//Ad Infinitum 11 - Math Programming Contest
//By derekhh
//Apr 18, 2015
//Reference
//An Arithmetic Function Arising From the Phi function
//Harold Shapiro, Princeton University, The American Mathematical Monthly, 1943
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 2000000;
bool isprime[MAXN + 1];
int eulerphi[MAXN + 1], f[MAXN + 1], factor[MAXN + 1];
void init()
{
memset(isprime, true, sizeof(isprime));
isprime[1] = false;
for (int i = 1; i <= MAXN; i++)
eulerphi[i] = i;
for (int i = 2; i <= MAXN; i++)
{
if (isprime[i])
{
factor[i] = i;
for (int j = i + i; j <= MAXN; j += i)
{
factor[j] = i;
isprime[j] = false;
}
}
}
for (int i = 1; i <= MAXN;i++)
{
if (isprime[i])
{
for (int j = i; j <= MAXN; j += i)
{
eulerphi[j] -= eulerphi[j] / i;
}
}
}
// f is the C function in the paper
f[1] = f[2] = 0;
for (int i = 3; i <= MAXN; i++)
f[i] = f[eulerphi[i]] + 1;
}
int base[4], power[4];
long long foo()
{
int nEven = 0;
long long ans = 0;
for (int i = 0; i < 4; i++)
{
if (base[i] % 2 == 0)
nEven++, ans--;
// Theorem 2 and 3
while (base[i] % 2 == 0)
{
ans += power[i];
base[i] /= 2;
}
// Theorem 5
while (base[i] != 1)
{
if (factor[base[i]] != 2)
ans += power[i] * f[factor[base[i]]];
base[i] /= factor[base[i]];
}
}
// Theorem 1
if (nEven >= 1)
ans += nEven - 1;
// C function is defined on phi*(n) = 2 and in this problem we need phi*(n) = 1
ans++;
return ans;
}
int main()
{
ios_base::sync_with_stdio(false);
init();
int t;
cin >> t;
while (t--)
{
bool baseAllOne = true;
for (int i = 0; i < 4; i++)
{
cin >> base[i] >> power[i];
if (base[i] == 1)
power[i] = 1;
else
baseAllOne = false;
}
if (baseAllOne)
{
cout << 0 << endl;
}
else
{
cout << foo() << endl;
}
}
return 0;
}