| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#include |
|
2
|
|
|
|
|
|
|
#include |
|
3
|
|
|
|
|
|
|
#include |
|
4
|
|
|
|
|
|
|
#include |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
#include "ptypes.h" |
|
7
|
|
|
|
|
|
|
#define FUNC_isqrt 1 |
|
8
|
|
|
|
|
|
|
#define FUNC_lcm_ui 1 |
|
9
|
|
|
|
|
|
|
#define FUNC_ctz 1 |
|
10
|
|
|
|
|
|
|
#define FUNC_log2floor 1 |
|
11
|
|
|
|
|
|
|
#define FUNC_is_perfect_square |
|
12
|
|
|
|
|
|
|
#define FUNC_next_prime_in_sieve 1 |
|
13
|
|
|
|
|
|
|
#define FUNC_prev_prime_in_sieve 1 |
|
14
|
|
|
|
|
|
|
#define FUNC_ipow 1 |
|
15
|
|
|
|
|
|
|
#include "util.h" |
|
16
|
|
|
|
|
|
|
#include "sieve.h" |
|
17
|
|
|
|
|
|
|
#include "primality.h" |
|
18
|
|
|
|
|
|
|
#include "cache.h" |
|
19
|
|
|
|
|
|
|
#include "legendre_phi.h" |
|
20
|
|
|
|
|
|
|
#include "prime_counts.h" |
|
21
|
|
|
|
|
|
|
#include "prime_powers.h" |
|
22
|
|
|
|
|
|
|
#include "factor.h" |
|
23
|
|
|
|
|
|
|
#include "mulmod.h" |
|
24
|
|
|
|
|
|
|
#include "constants.h" |
|
25
|
|
|
|
|
|
|
#include "montmath.h" |
|
26
|
|
|
|
|
|
|
#include "csprng.h" |
|
27
|
|
|
|
|
|
|
#include "inverse_interpolate.h" |
|
28
|
|
|
|
|
|
|
#include "rootmod.h" |
|
29
|
|
|
|
|
|
|
#include "lucas_seq.h" |
|
30
|
|
|
|
|
|
|
#include "sort.h" |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
static int _verbose = 0; |
|
33
|
8
|
|
|
|
|
|
void _XS_set_verbose(int v) { _verbose = v; } |
|
34
|
20578
|
|
|
|
|
|
int _XS_get_verbose(void) { return _verbose; } |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
static int _call_gmp = 0; |
|
37
|
120
|
|
|
|
|
|
void _XS_set_callgmp(int v) { _call_gmp = v; } |
|
38
|
107669
|
|
|
|
|
|
int _XS_get_callgmp(void) { return _call_gmp; } |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
static bool _secure = 0; |
|
41
|
0
|
|
|
|
|
|
void _XS_set_secure(void) { _secure = 1; } |
|
42
|
15
|
|
|
|
|
|
bool _XS_get_secure(void) { return _secure; } |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
/******************************************************************************/ |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
/* Returns 0 if not found, index+1 if found (returns leftmost if dups) */ |
|
47
|
126
|
|
|
|
|
|
unsigned long index_in_sorted_uv_array(UV v, UV* L, unsigned long len) |
|
48
|
|
|
|
|
|
|
{ |
|
49
|
|
|
|
|
|
|
unsigned long lo, hi; |
|
50
|
126
|
50
|
|
|
|
|
if (len == 0 || v < L[0] || v > L[len-1]) |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
51
|
57
|
|
|
|
|
|
return 0; |
|
52
|
69
|
|
|
|
|
|
lo = 0; |
|
53
|
69
|
|
|
|
|
|
hi = len-1; |
|
54
|
193
|
100
|
|
|
|
|
while (lo < hi) { |
|
55
|
124
|
|
|
|
|
|
unsigned long mid = lo + ((hi-lo) >> 1); |
|
56
|
124
|
100
|
|
|
|
|
if (L[mid] < v) lo = mid + 1; |
|
57
|
32
|
|
|
|
|
|
else hi = mid; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
69
|
100
|
|
|
|
|
return (L[lo] == v) ? lo+1 : 0; |
|
60
|
|
|
|
|
|
|
} |
|
61
|
35
|
|
|
|
|
|
unsigned long index_in_sorted_iv_array(IV v, IV* L, unsigned long len) |
|
62
|
|
|
|
|
|
|
{ |
|
63
|
|
|
|
|
|
|
unsigned long lo, hi; |
|
64
|
35
|
50
|
|
|
|
|
if (len == 0 || v < L[0] || v > L[len-1]) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
65
|
18
|
|
|
|
|
|
return 0; |
|
66
|
17
|
|
|
|
|
|
lo = 0; |
|
67
|
17
|
|
|
|
|
|
hi = len-1; |
|
68
|
46
|
100
|
|
|
|
|
while (lo < hi) { |
|
69
|
29
|
|
|
|
|
|
unsigned long mid = lo + ((hi-lo) >> 1); |
|
70
|
29
|
100
|
|
|
|
|
if (L[mid] < v) lo = mid + 1; |
|
71
|
9
|
|
|
|
|
|
else hi = mid; |
|
72
|
|
|
|
|
|
|
} |
|
73
|
17
|
100
|
|
|
|
|
return (L[lo] == v) ? lo+1 : 0; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
/* Do two sorted UV arrays have a non-zero intersection? */ |
|
77
|
0
|
|
|
|
|
|
bool do_arrays_intersect_uv(const UV* A, size_t alen, const UV* B, size_t blen) |
|
78
|
|
|
|
|
|
|
{ |
|
79
|
0
|
|
|
|
|
|
size_t ia = 0, ib = 0; |
|
80
|
0
|
0
|
|
|
|
|
while (ia < alen && ib < blen) { |
|
|
|
0
|
|
|
|
|
|
|
81
|
0
|
0
|
|
|
|
|
if (A[ia] == B[ib]) return 1; |
|
82
|
0
|
0
|
|
|
|
|
else if (A[ia] < B[ib]) ia++; |
|
83
|
0
|
|
|
|
|
|
else ib++; |
|
84
|
|
|
|
|
|
|
} |
|
85
|
0
|
|
|
|
|
|
return 0; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
0
|
|
|
|
|
|
bool do_arrays_intersect_iv(const IV* A, size_t alen, const IV* B, size_t blen) |
|
88
|
|
|
|
|
|
|
{ |
|
89
|
0
|
|
|
|
|
|
size_t ia = 0, ib = 0; |
|
90
|
0
|
0
|
|
|
|
|
while (ia < alen && ib < blen) { |
|
|
|
0
|
|
|
|
|
|
|
91
|
0
|
0
|
|
|
|
|
if (A[ia] == B[ib]) return 1; |
|
92
|
0
|
0
|
|
|
|
|
else if (A[ia] < B[ib]) ia++; |
|
93
|
0
|
|
|
|
|
|
else ib++; |
|
94
|
|
|
|
|
|
|
} |
|
95
|
0
|
|
|
|
|
|
return 0; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
/******************************************************************************/ |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
/* We'll use this little static sieve to quickly answer small values of |
|
101
|
|
|
|
|
|
|
* is_prime, next_prime, prev_prime, prime_count |
|
102
|
|
|
|
|
|
|
* for non-threaded Perl it's basically the same as getting the primary |
|
103
|
|
|
|
|
|
|
* cache. It guarantees we'll have an answer with no waiting on any version. |
|
104
|
|
|
|
|
|
|
*/ |
|
105
|
|
|
|
|
|
|
static const unsigned char prime_sieve30[] = |
|
106
|
|
|
|
|
|
|
{0x01,0x20,0x10,0x81,0x49,0x24,0xc2,0x06,0x2a,0xb0,0xe1,0x0c,0x15,0x59,0x12, |
|
107
|
|
|
|
|
|
|
0x61,0x19,0xf3,0x2c,0x2c,0xc4,0x22,0xa6,0x5a,0x95,0x98,0x6d,0x42,0x87,0xe1, |
|
108
|
|
|
|
|
|
|
0x59,0xa9,0xa9,0x1c,0x52,0xd2,0x21,0xd5,0xb3,0xaa,0x26,0x5c,0x0f,0x60,0xfc, |
|
109
|
|
|
|
|
|
|
0xab,0x5e,0x07,0xd1,0x02,0xbb,0x16,0x99,0x09,0xec,0xc5,0x47,0xb3,0xd4,0xc5, |
|
110
|
|
|
|
|
|
|
0xba,0xee,0x40,0xab,0x73,0x3e,0x85,0x4c,0x37,0x43,0x73,0xb0,0xde,0xa7,0x8e, |
|
111
|
|
|
|
|
|
|
0x8e,0x64,0x3e,0xe8,0x10,0xab,0x69,0xe5,0xf7,0x1a,0x7c,0x73,0xb9,0x8d,0x04, |
|
112
|
|
|
|
|
|
|
0x51,0x9a,0x6d,0x70,0xa7,0x78,0x2d,0x6d,0x27,0x7e,0x9a,0xd9,0x1c,0x5f,0xee, |
|
113
|
|
|
|
|
|
|
0xc7,0x38,0xd9,0xc3,0x7e,0x14,0x66,0x72,0xae,0x77,0xc1,0xdb,0x0c,0xcc,0xb2, |
|
114
|
|
|
|
|
|
|
0xa5,0x74,0xe3,0x58,0xd5,0x4b,0xa7,0xb3,0xb1,0xd9,0x09,0xe6,0x7d,0x23,0x7c, |
|
115
|
|
|
|
|
|
|
0x3c,0xd3,0x0e,0xc7,0xfd,0x4a,0x32,0x32,0xfd,0x4d,0xb5,0x6b,0xf3,0xa8,0xb3, |
|
116
|
|
|
|
|
|
|
0x85,0xcf,0xbc,0xf4,0x0e,0x34,0xbb,0x93,0xdb,0x07,0xe6,0xfe,0x6a,0x57,0xa3, |
|
117
|
|
|
|
|
|
|
0x8c,0x15,0x72,0xdb,0x69,0xd4,0xaf,0x59,0xdd,0xe1,0x3b,0x2e,0xb7,0xf9,0x2b, |
|
118
|
|
|
|
|
|
|
0xc5,0xd0,0x8b,0x63,0xf8,0x95,0xfa,0x77,0x40,0x97,0xea,0xd1,0x9f,0xaa,0x1c, |
|
119
|
|
|
|
|
|
|
0x48,0xae,0x67,0xf7,0xeb,0x79,0xa5,0x55,0xba,0xb2,0xb6,0x8f,0xd8,0x2d,0x6c, |
|
120
|
|
|
|
|
|
|
0x2a,0x35,0x54,0xfd,0x7c,0x9e,0xfa,0xdb,0x31,0x78,0xdd,0x3d,0x56,0x52,0xe7, |
|
121
|
|
|
|
|
|
|
0x73,0xb2,0x87,0x2e,0x76,0xe9,0x4f,0xa8,0x38,0x9d,0x5d,0x3f,0xcb,0xdb,0xad, |
|
122
|
|
|
|
|
|
|
0x51,0xa5,0xbf,0xcd,0x72,0xde,0xf7,0xbc,0xcb,0x49,0x2d,0x49,0x26,0xe6,0x1e, |
|
123
|
|
|
|
|
|
|
0x9f,0x98,0xe5,0xc6,0x9f,0x2f,0xbb,0x85,0x6b,0x65,0xf6,0x77,0x7c,0x57,0x8b, |
|
124
|
|
|
|
|
|
|
0xaa,0xef,0xd8,0x5e,0xa2,0x97,0xe1,0xdc,0x37,0xcd,0x1f,0xe6,0xfc,0xbb,0x8c, |
|
125
|
|
|
|
|
|
|
0xb7,0x4e,0xc7,0x3c,0x19,0xd5,0xa8,0x9e,0x67,0x4a,0xe3,0xf5,0x97,0x3a,0x7e, |
|
126
|
|
|
|
|
|
|
0x70,0x53,0xfd,0xd6,0xe5,0xb8,0x1c,0x6b,0xee,0xb1,0x9b,0xd1,0xeb,0x34,0xc2, |
|
127
|
|
|
|
|
|
|
0x23,0xeb,0x3a,0xf9,0xef,0x16,0xd6,0x4e,0x7d,0x16,0xcf,0xb8,0x1c,0xcb,0xe6, |
|
128
|
|
|
|
|
|
|
0x3c,0xda,0xf5,0xcf}; |
|
129
|
|
|
|
|
|
|
#define NPRIME_SIEVE30 (sizeof(prime_sieve30)/sizeof(prime_sieve30[0])) |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
static const unsigned short primes_tiny[] = |
|
132
|
|
|
|
|
|
|
{0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97, |
|
133
|
|
|
|
|
|
|
101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191, |
|
134
|
|
|
|
|
|
|
193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283, |
|
135
|
|
|
|
|
|
|
293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401, |
|
136
|
|
|
|
|
|
|
409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503}; |
|
137
|
|
|
|
|
|
|
#define NPRIMES_TINY (sizeof(primes_tiny)/sizeof(primes_tiny[0])) |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
/* Return true if n is prime, false if not. Do it fast. */ |
|
140
|
1597537
|
|
|
|
|
|
bool is_prime(UV n) |
|
141
|
|
|
|
|
|
|
{ |
|
142
|
1597537
|
100
|
|
|
|
|
if (n < UVCONST(500000000)) { |
|
143
|
|
|
|
|
|
|
|
|
144
|
1593513
|
100
|
|
|
|
|
if (n < 11) return 0xAC >> n & 1; |
|
145
|
1576772
|
100
|
|
|
|
|
if (is_divis_2_3_5_7(n)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
/* Check static tiny sieve */ |
|
148
|
515367
|
100
|
|
|
|
|
if (n < 30*NPRIME_SIEVE30) { |
|
149
|
23856
|
|
|
|
|
|
UV d = n/30, m = n - d*30; |
|
150
|
23856
|
|
|
|
|
|
return ((prime_sieve30[d] & masktab30[m]) == 0); |
|
151
|
|
|
|
|
|
|
} |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
/* Check primary cache */ |
|
154
|
491511
|
100
|
|
|
|
|
if (n <= get_prime_cache(0,0)) { |
|
155
|
|
|
|
|
|
|
const unsigned char* sieve; |
|
156
|
53255
|
|
|
|
|
|
int isprime = -1; |
|
157
|
97868
|
100
|
|
|
|
|
if (!(n%11) || !(n%13)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
158
|
44613
|
50
|
|
|
|
|
if (n <= get_prime_cache(0, &sieve)) { |
|
159
|
44613
|
|
|
|
|
|
UV d = n/30, m = n - d*30; |
|
160
|
44613
|
|
|
|
|
|
isprime = ((sieve[d] & masktab30[m]) == 0); |
|
161
|
|
|
|
|
|
|
} |
|
162
|
|
|
|
|
|
|
release_prime_cache(sieve); |
|
163
|
44613
|
50
|
|
|
|
|
if (isprime >= 0) |
|
164
|
44613
|
|
|
|
|
|
return isprime; |
|
165
|
|
|
|
|
|
|
} |
|
166
|
|
|
|
|
|
|
} |
|
167
|
442280
|
|
|
|
|
|
return is_prob_prime(n); |
|
168
|
|
|
|
|
|
|
} |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
|
|
171
|
81126
|
|
|
|
|
|
UV next_prime(UV n) |
|
172
|
|
|
|
|
|
|
{ |
|
173
|
|
|
|
|
|
|
UV m, next; |
|
174
|
|
|
|
|
|
|
|
|
175
|
81126
|
100
|
|
|
|
|
if (n < 30*NPRIME_SIEVE30) { |
|
176
|
80861
|
|
|
|
|
|
next = next_prime_in_sieve(prime_sieve30, n, 30*NPRIME_SIEVE30); |
|
177
|
80861
|
100
|
|
|
|
|
if (next != 0) return next; |
|
178
|
|
|
|
|
|
|
} |
|
179
|
|
|
|
|
|
|
|
|
180
|
266
|
50
|
|
|
|
|
if (n >= MPU_MAX_PRIME) return 0; /* Overflow */ |
|
181
|
|
|
|
|
|
|
|
|
182
|
266
|
100
|
|
|
|
|
if (n < get_prime_cache(0,0)) { |
|
183
|
|
|
|
|
|
|
const unsigned char* sieve; |
|
184
|
84
|
|
|
|
|
|
UV sieve_size = get_prime_cache(0, &sieve); |
|
185
|
84
|
50
|
|
|
|
|
next = (n < sieve_size) ? next_prime_in_sieve(sieve, n, sieve_size) : 0; |
|
186
|
|
|
|
|
|
|
release_prime_cache(sieve); |
|
187
|
84
|
50
|
|
|
|
|
if (next != 0) return next; |
|
188
|
|
|
|
|
|
|
} |
|
189
|
|
|
|
|
|
|
|
|
190
|
182
|
|
|
|
|
|
m = n % 30; |
|
191
|
|
|
|
|
|
|
do { /* Move forward one. */ |
|
192
|
3337
|
|
|
|
|
|
n += wheeladvance30[m]; |
|
193
|
3337
|
|
|
|
|
|
m = nextwheel30[m]; |
|
194
|
3337
|
100
|
|
|
|
|
} while (!is_prob_prime(n)); |
|
195
|
182
|
|
|
|
|
|
return n; |
|
196
|
|
|
|
|
|
|
} |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
|
|
199
|
17264
|
|
|
|
|
|
UV prev_prime(UV n) |
|
200
|
|
|
|
|
|
|
{ |
|
201
|
|
|
|
|
|
|
UV m, prev; |
|
202
|
|
|
|
|
|
|
|
|
203
|
17264
|
100
|
|
|
|
|
if (n < 30*NPRIME_SIEVE30) |
|
204
|
15071
|
|
|
|
|
|
return prev_prime_in_sieve(prime_sieve30, n); |
|
205
|
|
|
|
|
|
|
|
|
206
|
2193
|
100
|
|
|
|
|
if (n < get_prime_cache(0,0)) { |
|
207
|
|
|
|
|
|
|
const unsigned char* sieve; |
|
208
|
31
|
|
|
|
|
|
UV sieve_size = get_prime_cache(0, &sieve); |
|
209
|
31
|
50
|
|
|
|
|
prev = (n < sieve_size) ? prev_prime_in_sieve(sieve, n) : 0; |
|
210
|
|
|
|
|
|
|
release_prime_cache(sieve); |
|
211
|
31
|
50
|
|
|
|
|
if (prev != 0) return prev; |
|
212
|
|
|
|
|
|
|
} |
|
213
|
|
|
|
|
|
|
|
|
214
|
2162
|
|
|
|
|
|
m = n % 30; |
|
215
|
|
|
|
|
|
|
do { /* Move back one. */ |
|
216
|
9250
|
|
|
|
|
|
n -= wheelretreat30[m]; |
|
217
|
9250
|
|
|
|
|
|
m = prevwheel30[m]; |
|
218
|
9250
|
100
|
|
|
|
|
} while (!is_prob_prime(n)); |
|
219
|
2162
|
|
|
|
|
|
return n; |
|
220
|
|
|
|
|
|
|
} |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
/* We're trying to quickly give a reasonable monotonic upper prime count */ |
|
223
|
9547
|
|
|
|
|
|
UV max_nprimes(UV n) |
|
224
|
|
|
|
|
|
|
{ |
|
225
|
|
|
|
|
|
|
/* 2-bit error term of the 1..726 func so 0-143 gives exact results */ |
|
226
|
|
|
|
|
|
|
static const uint32_t _cor[9] = {0x415556af,0x01400001,0x00014140,0x01150100,0x14001515,0xa5515014,0x01555696,0xbea95501,0xeaabfaba}; |
|
227
|
|
|
|
|
|
|
double r; |
|
228
|
|
|
|
|
|
|
|
|
229
|
9547
|
100
|
|
|
|
|
if (n < 727) |
|
230
|
7615
|
|
|
|
|
|
return (13 + n - 7*n*n/16384)/4 |
|
231
|
7615
|
100
|
|
|
|
|
- (n < 144 ? _cor[n/16] >> n%16*2 & 3 : 0); |
|
232
|
|
|
|
|
|
|
|
|
233
|
1932
|
|
|
|
|
|
r = 1/log(n); |
|
234
|
|
|
|
|
|
|
|
|
235
|
1932
|
100
|
|
|
|
|
if (n < 59471) /* Special */ |
|
236
|
1894
|
|
|
|
|
|
return (UV)(n*r * (1 + r*(1 + 2.47687*r))) + 1; |
|
237
|
|
|
|
|
|
|
|
|
238
|
38
|
100
|
|
|
|
|
if (n < 1333894) /* Dusart 2018 x > 1 */ |
|
239
|
29
|
|
|
|
|
|
return n*r * (1 + r*(1 + 2.53816*r)); |
|
240
|
|
|
|
|
|
|
|
|
241
|
9
|
50
|
|
|
|
|
if (n < 883495117) /* Dusart 2022 x > 1 */ |
|
242
|
9
|
|
|
|
|
|
return n*r * (1 + r*(1 + r*(2 + 7.59*r))); |
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
/* We could use better bounds with Li(n) but that is MUCH slower. */ |
|
245
|
|
|
|
|
|
|
/* Use prime_count_upper(n) if you want tighter bounds. */ |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
/* Axler 2022 x > 1 Prp 4.6 */ |
|
248
|
0
|
|
|
|
|
|
return n*r * (1 + r*(1 + r*(2 + r*(6.024334 + r*(24.024334 + r*(120.12167 + r*(720.73002 + 6098*r))))))); |
|
249
|
|
|
|
|
|
|
} |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
/******************************************************************************/ |
|
252
|
|
|
|
|
|
|
/* PRINTING */ |
|
253
|
|
|
|
|
|
|
/******************************************************************************/ |
|
254
|
|
|
|
|
|
|
|
|
255
|
0
|
|
|
|
|
|
static int my_sprint(char* ptr, UV val) { |
|
256
|
|
|
|
|
|
|
int nchars; |
|
257
|
|
|
|
|
|
|
UV t; |
|
258
|
0
|
|
|
|
|
|
char *s = ptr; |
|
259
|
|
|
|
|
|
|
do { |
|
260
|
0
|
|
|
|
|
|
t = val / 10; *s++ = (char) ('0' + val - 10 * t); |
|
261
|
0
|
0
|
|
|
|
|
} while ((val = t)); |
|
262
|
0
|
|
|
|
|
|
nchars = s - ptr + 1; *s = '\n'; |
|
263
|
0
|
0
|
|
|
|
|
while (--s > ptr) { char c = *s; *s = *ptr; *ptr++ = c; } |
|
264
|
0
|
|
|
|
|
|
return nchars; |
|
265
|
|
|
|
|
|
|
} |
|
266
|
0
|
|
|
|
|
|
static char* write_buf(int fd, char* buf, char* bend) { |
|
267
|
0
|
|
|
|
|
|
int res = (int) write(fd, buf, bend-buf); |
|
268
|
0
|
0
|
|
|
|
|
if (res == -1) croak("print_primes write error"); |
|
269
|
0
|
|
|
|
|
|
return buf; |
|
270
|
|
|
|
|
|
|
} |
|
271
|
0
|
|
|
|
|
|
void print_primes(UV low, UV high, int fd) { |
|
272
|
|
|
|
|
|
|
char buf[8000+25]; |
|
273
|
0
|
|
|
|
|
|
char* bend = buf; |
|
274
|
0
|
0
|
|
|
|
|
if ((low <= 2) && (high >= 2)) bend += my_sprint(bend,2); |
|
|
|
0
|
|
|
|
|
|
|
275
|
0
|
0
|
|
|
|
|
if ((low <= 3) && (high >= 3)) bend += my_sprint(bend,3); |
|
|
|
0
|
|
|
|
|
|
|
276
|
0
|
0
|
|
|
|
|
if ((low <= 5) && (high >= 5)) bend += my_sprint(bend,5); |
|
|
|
0
|
|
|
|
|
|
|
277
|
0
|
0
|
|
|
|
|
if (low < 7) low = 7; |
|
278
|
|
|
|
|
|
|
|
|
279
|
0
|
0
|
|
|
|
|
if (low <= high) { |
|
280
|
|
|
|
|
|
|
unsigned char* segment; |
|
281
|
|
|
|
|
|
|
UV seg_base, seg_low, seg_high; |
|
282
|
0
|
|
|
|
|
|
void* ctx = start_segment_primes(low, high, &segment); |
|
283
|
0
|
0
|
|
|
|
|
while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) { |
|
284
|
0
|
0
|
|
|
|
|
START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high ) |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
285
|
0
|
|
|
|
|
|
bend += my_sprint(bend,p); |
|
286
|
0
|
0
|
|
|
|
|
if (bend-buf > 8000) { bend = write_buf(fd, buf, bend); } |
|
287
|
0
|
|
|
|
|
|
END_DO_FOR_EACH_SIEVE_PRIME |
|
288
|
|
|
|
|
|
|
} |
|
289
|
0
|
|
|
|
|
|
end_segment_primes(ctx); |
|
290
|
|
|
|
|
|
|
} |
|
291
|
0
|
0
|
|
|
|
|
if (bend > buf) { bend = write_buf(fd, buf, bend); } |
|
292
|
0
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
/******************************************************************************/ |
|
295
|
|
|
|
|
|
|
/* TOTIENT, MOEBIUS, MERTENS */ |
|
296
|
|
|
|
|
|
|
/******************************************************************************/ |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
/* Return a char array with lo-hi+1 elements. mu[k-lo] = µ(k) for k = lo .. hi. |
|
299
|
|
|
|
|
|
|
* It is the callers responsibility to call Safefree on the result. */ |
|
300
|
180
|
|
|
|
|
|
signed char* range_moebius(UV lo, UV hi) |
|
301
|
|
|
|
|
|
|
{ |
|
302
|
|
|
|
|
|
|
signed char* mu; |
|
303
|
180
|
|
|
|
|
|
UV i, sqrtn = isqrt(hi), count = hi-lo+1; |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
/* Kuznetsov indicates that the Deléglise & Rivat (1996) method can be |
|
306
|
|
|
|
|
|
|
* modified to work on logs, which allows us to operate with no |
|
307
|
|
|
|
|
|
|
* intermediate memory at all. Same time as the D&R method, less memory. */ |
|
308
|
|
|
|
|
|
|
unsigned char logp; |
|
309
|
|
|
|
|
|
|
UV nextlog, nextlogi; |
|
310
|
|
|
|
|
|
|
|
|
311
|
180
|
50
|
|
|
|
|
if (hi < lo) croak("range_mobius error hi %"UVuf" < lo %"UVuf"\n", hi, lo); |
|
312
|
|
|
|
|
|
|
|
|
313
|
180
|
|
|
|
|
|
Newz(0, mu, count, signed char); |
|
314
|
180
|
100
|
|
|
|
|
if (sqrtn*sqrtn != hi && sqrtn < (UVCONST(1)<<(BITS_PER_WORD/2))-1) sqrtn++; |
|
|
|
100
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
/* For small ranges, do it by hand */ |
|
317
|
180
|
100
|
|
|
|
|
if (hi < 100 || count <= 10 || (hi > (1UL<<25) && count < icbrt(hi)/4)) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
318
|
1118
|
100
|
|
|
|
|
for (i = 0; i < count; i++) |
|
319
|
999
|
|
|
|
|
|
mu[i] = (signed char)moebius(lo+i); |
|
320
|
119
|
|
|
|
|
|
return mu; |
|
321
|
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
|
|
323
|
61
|
|
|
|
|
|
logp = 1; nextlog = 3; /* 2+1 */ |
|
324
|
4243
|
50
|
|
|
|
|
START_DO_FOR_EACH_PRIME(2, sqrtn) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
325
|
4182
|
|
|
|
|
|
UV p2 = p*p; |
|
326
|
4182
|
100
|
|
|
|
|
if (p > nextlog) { |
|
327
|
187
|
|
|
|
|
|
logp += 2; /* logp is 1 | ceil(log(p)/log(2)) */ |
|
328
|
187
|
|
|
|
|
|
nextlog = ((nextlog-1)*4)+1; |
|
329
|
|
|
|
|
|
|
} |
|
330
|
147933046
|
50
|
|
|
|
|
for (i = P_GT_LO(p, p, lo); i >= lo && i <= hi; i += p) |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
331
|
147928864
|
|
|
|
|
|
mu[i-lo] += logp; |
|
332
|
28516137
|
50
|
|
|
|
|
for (i = P_GT_LO(p2, p2, lo); i >= lo && i <= hi; i += p2) |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
333
|
28511955
|
|
|
|
|
|
mu[i-lo] = (signed char)0x80; |
|
334
|
|
|
|
|
|
|
} END_DO_FOR_EACH_PRIME |
|
335
|
|
|
|
|
|
|
|
|
336
|
61
|
100
|
|
|
|
|
logp = (unsigned char)log2floor(lo); |
|
337
|
61
|
|
|
|
|
|
nextlogi = (UVCONST(2) << logp) - lo; |
|
338
|
63056304
|
100
|
|
|
|
|
for (i = 0; i < count; i++) { |
|
339
|
63056243
|
|
|
|
|
|
unsigned char a = mu[i]; |
|
340
|
63056243
|
100
|
|
|
|
|
if (i >= nextlogi) nextlogi = (UVCONST(2) << ++logp) - lo; |
|
341
|
63056243
|
100
|
|
|
|
|
if (a & 0x80) { a = 0; } |
|
342
|
38333733
|
100
|
|
|
|
|
else if (a >= logp) { a = 1 - 2*(a&1); } |
|
343
|
28394527
|
|
|
|
|
|
else { a = -1 + 2*(a&1); } |
|
344
|
63056243
|
|
|
|
|
|
mu[i] = a; |
|
345
|
|
|
|
|
|
|
} |
|
346
|
61
|
100
|
|
|
|
|
if (lo == 0) mu[0] = 0; |
|
347
|
|
|
|
|
|
|
|
|
348
|
61
|
|
|
|
|
|
return mu; |
|
349
|
|
|
|
|
|
|
} |
|
350
|
|
|
|
|
|
|
|
|
351
|
50
|
|
|
|
|
|
static short* mertens_array(UV hi) |
|
352
|
|
|
|
|
|
|
{ |
|
353
|
|
|
|
|
|
|
signed char* mu; |
|
354
|
|
|
|
|
|
|
short* M; |
|
355
|
|
|
|
|
|
|
UV i; |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
/* We could blend this with range_moebius but it seems not worth it. */ |
|
358
|
50
|
|
|
|
|
|
mu = range_moebius(0, hi); |
|
359
|
50
|
50
|
|
|
|
|
New(0, M, hi+1, short); |
|
360
|
50
|
|
|
|
|
|
M[0] = 0; |
|
361
|
63028331
|
100
|
|
|
|
|
for (i = 1; i <= hi; i++) |
|
362
|
63028281
|
|
|
|
|
|
M[i] = M[i-1] + mu[i]; |
|
363
|
50
|
|
|
|
|
|
Safefree(mu); |
|
364
|
|
|
|
|
|
|
|
|
365
|
50
|
|
|
|
|
|
return M; |
|
366
|
|
|
|
|
|
|
} |
|
367
|
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
#if 0 |
|
370
|
|
|
|
|
|
|
IV mertens(UV n) { |
|
371
|
|
|
|
|
|
|
/* See Deléglise and Rivat (1996) for O(n^2/3 log(log(n))^1/3) algorithm. |
|
372
|
|
|
|
|
|
|
* This implementation uses their lemma 2.1 directly, so is ~ O(n). |
|
373
|
|
|
|
|
|
|
* In serial it is quite a bit faster than segmented summation of mu |
|
374
|
|
|
|
|
|
|
* ranges, though the latter seems to be a favored method for GPUs. |
|
375
|
|
|
|
|
|
|
*/ |
|
376
|
|
|
|
|
|
|
UV u, j, m, nmk, maxmu; |
|
377
|
|
|
|
|
|
|
signed char* mu; |
|
378
|
|
|
|
|
|
|
short* M; /* 16 bits is enough range for all 32-bit M => 64-bit n */ |
|
379
|
|
|
|
|
|
|
IV sum; |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
if (n <= 1) return n; |
|
382
|
|
|
|
|
|
|
u = isqrt(n); |
|
383
|
|
|
|
|
|
|
maxmu = (n/(u+1)); /* maxmu lets us handle u < sqrt(n) */ |
|
384
|
|
|
|
|
|
|
if (maxmu < u) maxmu = u; |
|
385
|
|
|
|
|
|
|
mu = range_moebius(0, maxmu); |
|
386
|
|
|
|
|
|
|
New(0, M, maxmu+1, short); /* Works up to maxmu < 7613644886 */ |
|
387
|
|
|
|
|
|
|
M[0] = 0; |
|
388
|
|
|
|
|
|
|
for (j = 1; j <= maxmu; j++) |
|
389
|
|
|
|
|
|
|
M[j] = M[j-1] + mu[j]; |
|
390
|
|
|
|
|
|
|
sum = M[u]; |
|
391
|
|
|
|
|
|
|
for (m = 1; m <= u; m++) { |
|
392
|
|
|
|
|
|
|
if (mu[m] != 0) { |
|
393
|
|
|
|
|
|
|
IV inner_sum = 0; |
|
394
|
|
|
|
|
|
|
UV lower = (u/m) + 1; |
|
395
|
|
|
|
|
|
|
UV last_nmk = n/(m*lower); |
|
396
|
|
|
|
|
|
|
UV this_k = 0; |
|
397
|
|
|
|
|
|
|
UV next_k = n/(m*1); |
|
398
|
|
|
|
|
|
|
UV nmkm = m * 2; |
|
399
|
|
|
|
|
|
|
for (nmk = 1; nmk <= last_nmk; nmk++, nmkm += m) { |
|
400
|
|
|
|
|
|
|
this_k = next_k; |
|
401
|
|
|
|
|
|
|
next_k = n/nmkm; |
|
402
|
|
|
|
|
|
|
inner_sum += M[nmk] * (this_k - next_k); |
|
403
|
|
|
|
|
|
|
} |
|
404
|
|
|
|
|
|
|
sum += (mu[m] > 0) ? -inner_sum : inner_sum; |
|
405
|
|
|
|
|
|
|
} |
|
406
|
|
|
|
|
|
|
} |
|
407
|
|
|
|
|
|
|
Safefree(M); |
|
408
|
|
|
|
|
|
|
Safefree(mu); |
|
409
|
|
|
|
|
|
|
return sum; |
|
410
|
|
|
|
|
|
|
} |
|
411
|
|
|
|
|
|
|
#endif |
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
typedef struct { |
|
414
|
|
|
|
|
|
|
UV n; |
|
415
|
|
|
|
|
|
|
IV sum; |
|
416
|
|
|
|
|
|
|
} mertens_value_t; |
|
417
|
29552
|
|
|
|
|
|
static void _insert_mert_hash(mertens_value_t *H, UV hsize, UV n, IV sum) { |
|
418
|
29552
|
|
|
|
|
|
UV idx = n % hsize; |
|
419
|
29552
|
|
|
|
|
|
H[idx].n = n; |
|
420
|
29552
|
|
|
|
|
|
H[idx].sum = sum; |
|
421
|
29552
|
|
|
|
|
|
} |
|
422
|
178152
|
|
|
|
|
|
static int _get_mert_hash(mertens_value_t *H, UV hsize, UV n, IV *sum) { |
|
423
|
178152
|
|
|
|
|
|
UV idx = n % hsize; |
|
424
|
178152
|
100
|
|
|
|
|
if (H[idx].n == n) { |
|
425
|
148600
|
|
|
|
|
|
*sum = H[idx].sum; |
|
426
|
148600
|
|
|
|
|
|
return 1; |
|
427
|
|
|
|
|
|
|
} |
|
428
|
29552
|
|
|
|
|
|
return 0; |
|
429
|
|
|
|
|
|
|
} |
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
/* Thanks to Trizen for this algorithm. */ |
|
432
|
193296
|
|
|
|
|
|
static IV _rmertens(UV n, UV maxmu, short *M, mertens_value_t *H, UV hsize) { |
|
433
|
|
|
|
|
|
|
UV s, k, ns, nk, nk1, mk, mnk; |
|
434
|
|
|
|
|
|
|
IV sum; |
|
435
|
|
|
|
|
|
|
|
|
436
|
193296
|
100
|
|
|
|
|
if (n <= maxmu) |
|
437
|
15144
|
|
|
|
|
|
return M[n]; |
|
438
|
|
|
|
|
|
|
|
|
439
|
178152
|
100
|
|
|
|
|
if (_get_mert_hash(H, hsize, n, &sum)) |
|
440
|
148600
|
|
|
|
|
|
return sum; |
|
441
|
|
|
|
|
|
|
|
|
442
|
29552
|
|
|
|
|
|
s = isqrt(n); |
|
443
|
29552
|
|
|
|
|
|
ns = n / (s+1); |
|
444
|
29552
|
|
|
|
|
|
sum = 1; |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
#if 0 |
|
447
|
|
|
|
|
|
|
for (k = 2; k <= ns; k++) |
|
448
|
|
|
|
|
|
|
sum -= _rmertens(n/k, maxmu, M, H, hsize); |
|
449
|
|
|
|
|
|
|
for (k = 1; k <= s; k++) |
|
450
|
|
|
|
|
|
|
sum -= M[k] * (n/k - n/(k+1)); |
|
451
|
|
|
|
|
|
|
#else |
|
452
|
|
|
|
|
|
|
/* Take the above: merge the loops and iterate the divides. */ |
|
453
|
29552
|
100
|
|
|
|
|
if (s != ns && s != ns+1) croak("mertens s / ns"); |
|
|
|
50
|
|
|
|
|
|
|
454
|
29552
|
|
|
|
|
|
nk = n; |
|
455
|
29552
|
|
|
|
|
|
nk1 = n/2; |
|
456
|
29552
|
|
|
|
|
|
sum -= (nk - nk1); |
|
457
|
144868531
|
100
|
|
|
|
|
for (k = 2; k <= ns; k++) { |
|
458
|
144838979
|
|
|
|
|
|
nk = nk1; |
|
459
|
144838979
|
|
|
|
|
|
nk1 = n/(k+1); |
|
460
|
144838979
|
100
|
|
|
|
|
mnk = (nk <= maxmu) ? M[nk] : _rmertens(nk, maxmu, M, H, hsize); |
|
461
|
144838979
|
50
|
|
|
|
|
mk = (k <= maxmu) ? M[k] : _rmertens(k, maxmu, M, H, hsize); |
|
462
|
144838979
|
|
|
|
|
|
sum -= mnk + mk * (nk-nk1); |
|
463
|
|
|
|
|
|
|
} |
|
464
|
29552
|
100
|
|
|
|
|
if (s > ns) |
|
465
|
15144
|
|
|
|
|
|
sum -= _rmertens(s, maxmu, M, H, hsize) * (n/s - n/(s+1)); |
|
466
|
|
|
|
|
|
|
#endif |
|
467
|
|
|
|
|
|
|
|
|
468
|
29552
|
|
|
|
|
|
_insert_mert_hash(H, hsize, n, sum); |
|
469
|
29552
|
|
|
|
|
|
return sum; |
|
470
|
|
|
|
|
|
|
} |
|
471
|
|
|
|
|
|
|
|
|
472
|
50
|
|
|
|
|
|
static short* _prep_rmertens(UV n, UV* pmaxmu, UV* phsize) { |
|
473
|
50
|
|
|
|
|
|
UV j = icbrt(n); |
|
474
|
50
|
|
|
|
|
|
UV maxmu = 1 * j * j; |
|
475
|
50
|
|
|
|
|
|
UV hsize = next_prime(100 + 8*j); |
|
476
|
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
/* At large sizes, start clamping memory use. */ |
|
478
|
50
|
50
|
|
|
|
|
if (maxmu > 100000000UL) { |
|
479
|
|
|
|
|
|
|
/* Exponential decay, reduce by factor of 1 to 8 */ |
|
480
|
0
|
|
|
|
|
|
double rfactor = 1.0 + 7.0 * (1.0 - exp(-(double)maxmu/8000000000.0)); |
|
481
|
0
|
|
|
|
|
|
maxmu /= rfactor; |
|
482
|
0
|
|
|
|
|
|
hsize = next_prime(hsize * 16); /* Increase the result cache size */ |
|
483
|
|
|
|
|
|
|
} |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
#if BITS_PER_WORD == 64 |
|
486
|
|
|
|
|
|
|
/* A 16-bit signed short will overflow at maxmu > 7613644883 */ |
|
487
|
50
|
50
|
|
|
|
|
if (maxmu > UVCONST(7613644883)) maxmu = UVCONST(7613644883); |
|
488
|
|
|
|
|
|
|
#endif |
|
489
|
|
|
|
|
|
|
|
|
490
|
50
|
|
|
|
|
|
*pmaxmu = maxmu; |
|
491
|
50
|
|
|
|
|
|
*phsize = hsize; |
|
492
|
50
|
|
|
|
|
|
return mertens_array(maxmu); |
|
493
|
|
|
|
|
|
|
} |
|
494
|
|
|
|
|
|
|
|
|
495
|
52
|
|
|
|
|
|
IV mertens(UV n) { |
|
496
|
|
|
|
|
|
|
UV j, maxmu, hsize; |
|
497
|
|
|
|
|
|
|
short* M; /* 16 bits is enough range for all 32-bit M => 64-bit n */ |
|
498
|
|
|
|
|
|
|
mertens_value_t *H; /* Cache of calculated values */ |
|
499
|
|
|
|
|
|
|
IV sum; |
|
500
|
|
|
|
|
|
|
|
|
501
|
52
|
100
|
|
|
|
|
if (n <= 512) { |
|
502
|
|
|
|
|
|
|
static signed char MV16[33] = {0,-1,-4,-3,-1,-4,2,-4,-2,-1,0,-4,-5,-3,3,-1,-1,-3,-7,-2,-4,2,1,-1,-2,1,1,-3,-6,-6,-6,-5,-4}; |
|
503
|
18
|
|
|
|
|
|
j = n/16; |
|
504
|
18
|
|
|
|
|
|
sum = MV16[j]; |
|
505
|
79
|
100
|
|
|
|
|
for (j = j*16 + 1; j <= n; j++) |
|
506
|
61
|
|
|
|
|
|
sum += moebius(j); |
|
507
|
18
|
|
|
|
|
|
return sum; |
|
508
|
|
|
|
|
|
|
} |
|
509
|
|
|
|
|
|
|
|
|
510
|
34
|
|
|
|
|
|
M = _prep_rmertens(n, &maxmu, &hsize); |
|
511
|
34
|
50
|
|
|
|
|
Newz(0, H, hsize, mertens_value_t); |
|
512
|
|
|
|
|
|
|
|
|
513
|
34
|
|
|
|
|
|
sum = _rmertens(n, maxmu, M, H, hsize); |
|
514
|
|
|
|
|
|
|
|
|
515
|
34
|
|
|
|
|
|
Safefree(H); |
|
516
|
34
|
|
|
|
|
|
Safefree(M); |
|
517
|
34
|
|
|
|
|
|
return sum; |
|
518
|
|
|
|
|
|
|
} |
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
static const signed char _small_liouville[16] = {-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,-1,1,1}; |
|
521
|
|
|
|
|
|
|
|
|
522
|
41
|
|
|
|
|
|
static signed char* liouville_array(UV hi) |
|
523
|
|
|
|
|
|
|
{ |
|
524
|
|
|
|
|
|
|
signed char* l; |
|
525
|
|
|
|
|
|
|
UV a, b, k; |
|
526
|
|
|
|
|
|
|
|
|
527
|
41
|
100
|
|
|
|
|
if (hi < 16) hi = 15; |
|
528
|
41
|
|
|
|
|
|
New(0, l, hi+1, signed char); |
|
529
|
41
|
|
|
|
|
|
memcpy(l, _small_liouville, 16); |
|
530
|
41
|
100
|
|
|
|
|
if (hi >= 16) memset(l+16, -1, hi-16+1); |
|
531
|
|
|
|
|
|
|
|
|
532
|
75
|
100
|
|
|
|
|
for (a = 16; a <= hi; a = b+1) { |
|
533
|
|
|
|
|
|
|
/* TODO: 2*a >= UV_MAX */ |
|
534
|
34
|
|
|
|
|
|
b = (2*a-1 <= hi) ? 2*a-1 : hi; |
|
535
|
127
|
50
|
|
|
|
|
START_DO_FOR_EACH_PRIME(2, isqrt(b)) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
536
|
946
|
100
|
|
|
|
|
for (k = 2*p; k <= b; k += p) { |
|
537
|
853
|
100
|
|
|
|
|
if (k >= a) |
|
538
|
319
|
|
|
|
|
|
l[k] = -1 * l[k/p]; |
|
539
|
|
|
|
|
|
|
} |
|
540
|
|
|
|
|
|
|
} END_DO_FOR_EACH_PRIME |
|
541
|
|
|
|
|
|
|
} |
|
542
|
|
|
|
|
|
|
|
|
543
|
41
|
|
|
|
|
|
return l; |
|
544
|
|
|
|
|
|
|
} |
|
545
|
|
|
|
|
|
|
|
|
546
|
60
|
|
|
|
|
|
int liouville(UV n) { |
|
547
|
60
|
50
|
|
|
|
|
if (n < 16) |
|
548
|
0
|
|
|
|
|
|
return _small_liouville[n]; |
|
549
|
|
|
|
|
|
|
else |
|
550
|
60
|
100
|
|
|
|
|
return( (prime_bigomega(n) & 1) ? -1 : 1 ); |
|
551
|
|
|
|
|
|
|
} |
|
552
|
|
|
|
|
|
|
|
|
553
|
57
|
|
|
|
|
|
IV sumliouville(UV n) { |
|
554
|
|
|
|
|
|
|
short* M; |
|
555
|
|
|
|
|
|
|
mertens_value_t *H; |
|
556
|
|
|
|
|
|
|
UV j, maxmu, hsize, k, nk, sqrtn; |
|
557
|
|
|
|
|
|
|
IV sum; |
|
558
|
|
|
|
|
|
|
|
|
559
|
57
|
100
|
|
|
|
|
if (n <= 96) { |
|
560
|
41
|
|
|
|
|
|
signed char* l = liouville_array(n); |
|
561
|
861
|
100
|
|
|
|
|
for (sum = 0, j = 1; j <= n; j++) |
|
562
|
820
|
|
|
|
|
|
sum += l[j]; |
|
563
|
41
|
|
|
|
|
|
Safefree(l); |
|
564
|
41
|
|
|
|
|
|
return sum; |
|
565
|
|
|
|
|
|
|
} |
|
566
|
|
|
|
|
|
|
|
|
567
|
16
|
|
|
|
|
|
M = _prep_rmertens(n, &maxmu, &hsize); |
|
568
|
16
|
50
|
|
|
|
|
Newz(0, H, hsize, mertens_value_t); |
|
569
|
|
|
|
|
|
|
|
|
570
|
16
|
|
|
|
|
|
sqrtn = isqrt(n); |
|
571
|
16
|
|
|
|
|
|
sum = _rmertens(n, maxmu, M, H, hsize); |
|
572
|
109730
|
50
|
|
|
|
|
for (k = 2; k <= sqrtn; k++) { |
|
573
|
109730
|
|
|
|
|
|
nk = n / (k*k); |
|
574
|
109730
|
100
|
|
|
|
|
if (nk == 1) break; |
|
575
|
109714
|
100
|
|
|
|
|
sum += (nk <= maxmu) ? M[nk] : _rmertens(nk, maxmu, M, H, hsize); |
|
576
|
|
|
|
|
|
|
} |
|
577
|
16
|
|
|
|
|
|
sum += (sqrtn + 1 - k); /* all k where n/(k*k) == 1 */ |
|
578
|
|
|
|
|
|
|
/* TODO: find method to get exact number of n/(k*k)==1 .. 4. Halves k */ |
|
579
|
|
|
|
|
|
|
/* Ends up with method like Lehmer's g. */ |
|
580
|
|
|
|
|
|
|
|
|
581
|
16
|
|
|
|
|
|
Safefree(H); |
|
582
|
16
|
|
|
|
|
|
Safefree(M); |
|
583
|
16
|
|
|
|
|
|
return sum; |
|
584
|
|
|
|
|
|
|
} |
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
/* This paper shows an algorithm for sieving an interval: |
|
587
|
|
|
|
|
|
|
*https://www.ams.org/journals/mcom/2008-77-263/S0025-5718-08-02036-X/S0025-5718-08-02036-X.pdf */ |
|
588
|
0
|
|
|
|
|
|
signed char* range_liouville(UV lo, UV hi) |
|
589
|
|
|
|
|
|
|
{ |
|
590
|
|
|
|
|
|
|
UV i; |
|
591
|
|
|
|
|
|
|
signed char *l; |
|
592
|
|
|
|
|
|
|
unsigned char *nf; |
|
593
|
|
|
|
|
|
|
|
|
594
|
0
|
0
|
|
|
|
|
if (hi < lo) croak("range_liouvillle error hi %"UVuf" < lo %"UVuf"\n",hi,lo); |
|
595
|
0
|
|
|
|
|
|
nf = range_nfactor_sieve(lo, hi, 1); |
|
596
|
0
|
|
|
|
|
|
New(0, l, hi-lo+1, signed char); |
|
597
|
0
|
0
|
|
|
|
|
for (i = 0; i < hi-lo+1; i++) |
|
598
|
0
|
0
|
|
|
|
|
l[i] = (nf[i] & 1) ? -1 : 1; |
|
599
|
0
|
|
|
|
|
|
Safefree(nf); |
|
600
|
0
|
|
|
|
|
|
return l; |
|
601
|
|
|
|
|
|
|
} |
|
602
|
|
|
|
|
|
|
|
|
603
|
267
|
|
|
|
|
|
UV carmichael_lambda(UV n) { |
|
604
|
267
|
|
|
|
|
|
const unsigned char _totient[8] = {0,1,1,2,2,4,2,6}; |
|
605
|
|
|
|
|
|
|
uint32_t i; |
|
606
|
267
|
|
|
|
|
|
UV lambda = 1; |
|
607
|
|
|
|
|
|
|
|
|
608
|
267
|
100
|
|
|
|
|
if (n < 8) return _totient[n]; |
|
609
|
259
|
100
|
|
|
|
|
if ((n & (n-1)) == 0) return n >> 2; |
|
610
|
|
|
|
|
|
|
|
|
611
|
250
|
50
|
|
|
|
|
i = ctz(n); |
|
612
|
250
|
100
|
|
|
|
|
if (i > 0) { |
|
613
|
94
|
|
|
|
|
|
n >>= i; |
|
614
|
94
|
100
|
|
|
|
|
lambda <<= (i>2) ? i-2 : i-1; |
|
615
|
|
|
|
|
|
|
} |
|
616
|
|
|
|
|
|
|
{ |
|
617
|
|
|
|
|
|
|
#if 1 /* This is very slightly faster */ |
|
618
|
|
|
|
|
|
|
UV fac[MPU_MAX_FACTORS+1]; |
|
619
|
250
|
|
|
|
|
|
uint32_t nfactors = factor(n, fac); |
|
620
|
590
|
100
|
|
|
|
|
for (i = 0; i < nfactors; i++) { |
|
621
|
340
|
|
|
|
|
|
UV p = fac[i], pk = p-1; |
|
622
|
387
|
100
|
|
|
|
|
while (i+1 < nfactors && p == fac[i+1]) { |
|
|
|
100
|
|
|
|
|
|
|
623
|
47
|
|
|
|
|
|
i++; |
|
624
|
47
|
|
|
|
|
|
pk *= p; |
|
625
|
|
|
|
|
|
|
} |
|
626
|
340
|
|
|
|
|
|
lambda = lcm_ui(lambda, pk); |
|
627
|
|
|
|
|
|
|
} |
|
628
|
|
|
|
|
|
|
#else |
|
629
|
|
|
|
|
|
|
factored_t nf = factorint(n); |
|
630
|
|
|
|
|
|
|
for (i = 0; i < nf.nfactors; i++) { |
|
631
|
|
|
|
|
|
|
UV p = nf.f[i], pk = p-1, e = nf.e[i]; |
|
632
|
|
|
|
|
|
|
while (e-- > 1) |
|
633
|
|
|
|
|
|
|
pk *= p; |
|
634
|
|
|
|
|
|
|
lambda = lcm_ui(lambda, pk); |
|
635
|
|
|
|
|
|
|
} |
|
636
|
|
|
|
|
|
|
#endif |
|
637
|
|
|
|
|
|
|
} |
|
638
|
250
|
|
|
|
|
|
return lambda; |
|
639
|
|
|
|
|
|
|
} |
|
640
|
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
/******************************************************************************/ |
|
643
|
|
|
|
|
|
|
/* POWERS and ROOTS */ |
|
644
|
|
|
|
|
|
|
/******************************************************************************/ |
|
645
|
|
|
|
|
|
|
|
|
646
|
44318
|
|
|
|
|
|
static float _cbrtf(float x) |
|
647
|
|
|
|
|
|
|
{ |
|
648
|
|
|
|
|
|
|
float t, r; |
|
649
|
44318
|
|
|
|
|
|
union { float f; uint32_t i; } xx = { x }; |
|
650
|
44318
|
|
|
|
|
|
xx.i = (xx.i + 2129874493U)/3; |
|
651
|
44318
|
|
|
|
|
|
t = xx.f; |
|
652
|
|
|
|
|
|
|
/* One round of Halley's method gets to 15.53 bits */ |
|
653
|
44318
|
|
|
|
|
|
r = t * t * t; |
|
654
|
44318
|
|
|
|
|
|
t *= (x + (x + r)) / ((x + r) + r); |
|
655
|
|
|
|
|
|
|
#if BITS_PER_WORD > 45 |
|
656
|
|
|
|
|
|
|
/* A second round gets us the 21.5 bits we need. */ |
|
657
|
44318
|
|
|
|
|
|
r = t * t * t; |
|
658
|
44318
|
|
|
|
|
|
t += t * (x - r) / (x + (r + r)); |
|
659
|
|
|
|
|
|
|
#endif |
|
660
|
44318
|
|
|
|
|
|
return t; |
|
661
|
|
|
|
|
|
|
} |
|
662
|
44318
|
|
|
|
|
|
uint32_t icbrt(UV n) { |
|
663
|
44318
|
50
|
|
|
|
|
if (n > 0) { |
|
664
|
44318
|
|
|
|
|
|
uint32_t root = (float)(_cbrtf((float)n) + 0.375f); |
|
665
|
44318
|
|
|
|
|
|
UV rem = n - (UV)root * root * root; |
|
666
|
44318
|
|
|
|
|
|
return root - ((IV)rem < 0); |
|
667
|
|
|
|
|
|
|
} |
|
668
|
0
|
|
|
|
|
|
return 0; |
|
669
|
|
|
|
|
|
|
} |
|
670
|
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
/******************************************************************************/ |
|
672
|
|
|
|
|
|
|
|
|
673
|
78625
|
|
|
|
|
|
static UV _ipow(unsigned b, unsigned e, unsigned bit) |
|
674
|
|
|
|
|
|
|
{ |
|
675
|
78625
|
|
|
|
|
|
UV r = b; |
|
676
|
259964
|
100
|
|
|
|
|
while (bit >>= 1) { |
|
677
|
181339
|
|
|
|
|
|
r *= r; |
|
678
|
181339
|
100
|
|
|
|
|
if (e & bit) |
|
679
|
94064
|
|
|
|
|
|
r *= b; |
|
680
|
|
|
|
|
|
|
} |
|
681
|
78625
|
|
|
|
|
|
return r; |
|
682
|
|
|
|
|
|
|
} |
|
683
|
|
|
|
|
|
|
/* Estimate the kth root of n. |
|
684
|
|
|
|
|
|
|
* |
|
685
|
|
|
|
|
|
|
* Returns exact root if n is a perfect power, otherwise either root or root+1. |
|
686
|
|
|
|
|
|
|
* Requires k >= 3 so a float can exactly represent the kth root. |
|
687
|
|
|
|
|
|
|
* |
|
688
|
|
|
|
|
|
|
* This version is heavily trimmed for internal use with rootint's prefilters. |
|
689
|
|
|
|
|
|
|
* |
|
690
|
|
|
|
|
|
|
* n > 1 |
|
691
|
|
|
|
|
|
|
* n>>k != 0 <=> n < 1<
|
|
692
|
|
|
|
|
|
|
* 4 < k <= MAX_IROOTN (32-bit: 10 64-bit: 15) |
|
693
|
|
|
|
|
|
|
*/ |
|
694
|
78625
|
|
|
|
|
|
static uint32_t _est_root(UV n, unsigned k, unsigned msbit) |
|
695
|
|
|
|
|
|
|
{ |
|
696
|
78625
|
|
|
|
|
|
const float y = n; |
|
697
|
78625
|
|
|
|
|
|
union { float f; uint32_t i; } both32 = { y }; |
|
698
|
78625
|
|
|
|
|
|
const uint32_t float_one = (uint32_t)127 << 23; |
|
699
|
|
|
|
|
|
|
float x, err, xk; |
|
700
|
|
|
|
|
|
|
|
|
701
|
78625
|
100
|
|
|
|
|
if (k == 4) return (int)(sqrtf(sqrtf(y)) + 0.5f); |
|
702
|
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
/* The standard floating-point trick for an initial estimate, |
|
704
|
|
|
|
|
|
|
* but using two constants for variable k. The constants |
|
705
|
|
|
|
|
|
|
* are chosen to be perfect for k=5 and very close to ideal |
|
706
|
|
|
|
|
|
|
* for k=6. As k increases, the relative accuracy needed |
|
707
|
|
|
|
|
|
|
* decreases, so higher k can tolerate a lot of slop. |
|
708
|
|
|
|
|
|
|
* |
|
709
|
|
|
|
|
|
|
* One problem is that n==1 underflows. We could fix this |
|
710
|
|
|
|
|
|
|
* (add k<<20 before division and subtract 1<<10 after), but |
|
711
|
|
|
|
|
|
|
* it is simpler just to special case n==1. */ |
|
712
|
|
|
|
|
|
|
|
|
713
|
67631
|
|
|
|
|
|
both32.i = (both32.i - float_one - 89788) / k + float_one - 282298; |
|
714
|
67631
|
|
|
|
|
|
x = both32.f; |
|
715
|
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
/* Improve it with one round of Halley's method. |
|
717
|
|
|
|
|
|
|
* |
|
718
|
|
|
|
|
|
|
* Newton's (quadratic) method for a root of x^k - y == 0 is |
|
719
|
|
|
|
|
|
|
* x += (y - x^k) / (k * x^(k-1)) |
|
720
|
|
|
|
|
|
|
* which simplifies a lot for fixed k, but for variable k, |
|
721
|
|
|
|
|
|
|
* Halley's (cubic) method is not much more complex: |
|
722
|
|
|
|
|
|
|
* x += 2*x*(y-x^k) / (k*(y+x^k) - (y - x^k)) |
|
723
|
|
|
|
|
|
|
* For all k >= 5, one round suffices. |
|
724
|
|
|
|
|
|
|
* Since k < 5 is handled already, this works for us. */ |
|
725
|
|
|
|
|
|
|
|
|
726
|
67631
|
|
|
|
|
|
xk = x; |
|
727
|
226982
|
100
|
|
|
|
|
while (msbit >>= 1) { |
|
728
|
159351
|
|
|
|
|
|
xk *= xk; |
|
729
|
159351
|
100
|
|
|
|
|
if (k & msbit) |
|
730
|
94064
|
|
|
|
|
|
xk *= x; |
|
731
|
|
|
|
|
|
|
} |
|
732
|
|
|
|
|
|
|
|
|
733
|
67631
|
|
|
|
|
|
err = y - xk; |
|
734
|
67631
|
|
|
|
|
|
x += 2.0f*x*err / ((float)(int)k*(y+xk) - err); |
|
735
|
67631
|
|
|
|
|
|
return (int)(x + 0.5f); |
|
736
|
|
|
|
|
|
|
} |
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
/* Trimmed for internal use. k MUST be between 4 and 15, n > 1 */ |
|
739
|
|
|
|
|
|
|
#define MAX_IROOTN ((BITS_PER_WORD == 64) ? 15 : 10) |
|
740
|
51746
|
|
|
|
|
|
static uint32_t _irootn(UV n, uint32_t k) |
|
741
|
|
|
|
|
|
|
{ |
|
742
|
51746
|
100
|
|
|
|
|
uint32_t const msb = 4 << (k >= 8); |
|
743
|
51746
|
|
|
|
|
|
uint32_t const r = _est_root(n,k,msb); |
|
744
|
51746
|
|
|
|
|
|
return r - ((IV)(n - _ipow(r,k,msb)) < 0); |
|
745
|
|
|
|
|
|
|
} |
|
746
|
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
/******************************************************************************/ |
|
748
|
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
#if BITS_PER_WORD == 64 |
|
750
|
|
|
|
|
|
|
static const uint32_t root_max[1+MPU_MAX_POW3] = {0,0,4294967295U,2642245,65535,7131,1625,565,255,138,84,56,40,30,23,19,15,13,11,10,9,8,7,6,6,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3}; |
|
751
|
|
|
|
|
|
|
#else |
|
752
|
|
|
|
|
|
|
static const uint32_t root_max[1+MPU_MAX_POW3] = {0,0,65535,1625,255,84,40,23,15,11,9,7,6,5,4,4,3,3,3,3,3}; |
|
753
|
|
|
|
|
|
|
#endif |
|
754
|
|
|
|
|
|
|
|
|
755
|
140179
|
|
|
|
|
|
UV rootint(UV n, uint32_t k) |
|
756
|
|
|
|
|
|
|
{ |
|
757
|
140179
|
100
|
|
|
|
|
if (n <= 1) return (k != 0 && n != 0); |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
|
|
759
|
132032
|
|
|
|
|
|
switch (k) { |
|
760
|
0
|
|
|
|
|
|
case 0: return 0; |
|
761
|
8
|
|
|
|
|
|
case 1: return n; |
|
762
|
18435
|
|
|
|
|
|
case 2: return isqrt(n); |
|
763
|
21608
|
|
|
|
|
|
case 3: return icbrt(n); |
|
764
|
10991
|
|
|
|
|
|
case 4: return _irootn(n,4); |
|
765
|
8371
|
|
|
|
|
|
case 5: return _irootn(n,5); |
|
766
|
72619
|
|
|
|
|
|
default: break; |
|
767
|
|
|
|
|
|
|
} |
|
768
|
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
/* MAX_IROOTN < BITS_PER_WORD/2 < MPU_MAX_POW3 */ |
|
770
|
|
|
|
|
|
|
/* 32-bit: 10 16 20 */ |
|
771
|
|
|
|
|
|
|
/* 64-bit: 15 32 40 */ |
|
772
|
|
|
|
|
|
|
|
|
773
|
72619
|
100
|
|
|
|
|
if (n >> k == 0) return 1; |
|
774
|
|
|
|
|
|
|
|
|
775
|
40932
|
100
|
|
|
|
|
if (k <= MAX_IROOTN) return _irootn(n,k); |
|
776
|
|
|
|
|
|
|
|
|
777
|
8548
|
100
|
|
|
|
|
if (k > MPU_MAX_POW3) return 1 + (k < BITS_PER_WORD); |
|
|
|
100
|
|
|
|
|
|
|
778
|
8175
|
100
|
|
|
|
|
if (k >= BITS_PER_WORD/2) return 2 + (n >= ipow(3,k)); |
|
|
|
100
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
/* k is now in range 11-15 (32-bit), 16-31 (64-bit). Binary search. */ |
|
781
|
|
|
|
|
|
|
{ |
|
782
|
7792
|
50
|
|
|
|
|
uint32_t lo = 1U << (log2floor(n)/k); |
|
783
|
7792
|
|
|
|
|
|
uint32_t hi = root_max[k]; |
|
784
|
7792
|
100
|
|
|
|
|
if (hi >= lo*2) hi = lo*2 - 1; |
|
785
|
|
|
|
|
|
|
|
|
786
|
15947
|
100
|
|
|
|
|
while (lo < hi) { |
|
787
|
8155
|
|
|
|
|
|
uint32_t mid = lo + (hi-lo+1)/2; |
|
788
|
8155
|
100
|
|
|
|
|
if (ipow(mid,k) > n) hi = mid-1; |
|
789
|
1584
|
|
|
|
|
|
else lo = mid; |
|
790
|
|
|
|
|
|
|
} |
|
791
|
7792
|
|
|
|
|
|
return lo; |
|
792
|
|
|
|
|
|
|
} |
|
793
|
|
|
|
|
|
|
} |
|
794
|
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
/* Like ipow but returns UV_MAX if overflow */ |
|
796
|
114081
|
|
|
|
|
|
UV ipowsafe(UV n, UV k) { |
|
797
|
114081
|
|
|
|
|
|
UV p = 1; |
|
798
|
|
|
|
|
|
|
|
|
799
|
114081
|
100
|
|
|
|
|
if (n == 0) return !k; /* 0^0 => 1, 0^x => 0 */ |
|
800
|
114071
|
100
|
|
|
|
|
if (n == 1) return 1; /* 1^0 => 1, 1^x => 1 */ |
|
801
|
|
|
|
|
|
|
|
|
802
|
106146
|
100
|
|
|
|
|
if (k <= MPU_MAX_POW3) { |
|
803
|
102752
|
100
|
|
|
|
|
if (k == 0) return 1; |
|
804
|
102735
|
100
|
|
|
|
|
if (k == 1) return n; |
|
805
|
102684
|
100
|
|
|
|
|
return (n <= root_max[k]) ? ipow(n,k) : UV_MAX; |
|
806
|
|
|
|
|
|
|
} |
|
807
|
|
|
|
|
|
|
|
|
808
|
16203
|
100
|
|
|
|
|
while (k) { |
|
809
|
15916
|
100
|
|
|
|
|
if (k & 1) { if (UV_MAX/n < p) return UV_MAX; p *= n; } |
|
|
|
100
|
|
|
|
|
|
|
810
|
15163
|
|
|
|
|
|
k >>= 1; |
|
811
|
15163
|
100
|
|
|
|
|
if (k) { if (UV_MAX/n < n) return UV_MAX; n *= n; } |
|
|
|
100
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
} |
|
813
|
287
|
|
|
|
|
|
return p; |
|
814
|
|
|
|
|
|
|
} |
|
815
|
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
/******************************************************************************/ |
|
818
|
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
/* Mod 32 filters for allowable k-th root */ |
|
820
|
|
|
|
|
|
|
static const uint32_t _rootmask32[41] = { |
|
821
|
|
|
|
|
|
|
0x00000000,0x00000000,0xfdfcfdec,0x54555454,0xfffcfffc, /* 0-4 */ |
|
822
|
|
|
|
|
|
|
0x55555554,0xfdfdfdfc,0x55555554,0xfffffffc,0x55555554,0xfdfdfdfc,/* 5-10 */ |
|
823
|
|
|
|
|
|
|
0x55555554,0xfffdfffc,0xd5555556,0xfdfdfdfc,0xf57d57d6,0xfffffffc,/* 11-16 */ |
|
824
|
|
|
|
|
|
|
0xffffd556,0xfdfdfdfe,0xd57ffffe,0xfffdfffc,0xffd7ff7e,0xfdfdfdfe,/* 17-22 */ |
|
825
|
|
|
|
|
|
|
0xffffd7fe,0xfffffffc,0xffffffd6,0xfdfffdfe,0xd7fffffe,0xfffdfffe,/* 23-28 */ |
|
826
|
|
|
|
|
|
|
0xfff7fffe,0xfdfffffe,0xfffff7fe,0xfffffffc,0xfffffff6,0xfffffdfe,/* 29-34 */ |
|
827
|
|
|
|
|
|
|
0xf7fffffe,0xfffdfffe,0xfff7fffe,0xfdfffffe,0xfffff7fe,0xfffffffc /* 35-40 */ |
|
828
|
|
|
|
|
|
|
}; |
|
829
|
|
|
|
|
|
|
|
|
830
|
62594
|
|
|
|
|
|
bool is_power_ret(UV n, uint32_t k, uint32_t *root) |
|
831
|
|
|
|
|
|
|
{ |
|
832
|
|
|
|
|
|
|
uint32_t r, msbit; |
|
833
|
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
/* Simple edge cases */ |
|
835
|
62594
|
100
|
|
|
|
|
if (n < 2 || k == 1) { |
|
|
|
100
|
|
|
|
|
|
|
836
|
27
|
100
|
|
|
|
|
if (root) *root = n; |
|
837
|
27
|
|
|
|
|
|
return 1; |
|
838
|
|
|
|
|
|
|
} |
|
839
|
62567
|
50
|
|
|
|
|
if (k == 0) |
|
840
|
0
|
|
|
|
|
|
return 0; |
|
841
|
62567
|
100
|
|
|
|
|
if (k > MPU_MAX_POW3) { |
|
842
|
1
|
50
|
|
|
|
|
if (root) *root = 2; |
|
843
|
1
|
50
|
|
|
|
|
return (k < BITS_PER_WORD && n == (UV)1 << k); |
|
|
|
50
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
} |
|
845
|
|
|
|
|
|
|
|
|
846
|
62566
|
100
|
|
|
|
|
if (k == 2) return is_perfect_square_ret(n,root); |
|
847
|
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
/* Filter out many numbers which cannot be k-th roots */ |
|
849
|
62501
|
100
|
|
|
|
|
if ((1U << (n&31)) & _rootmask32[k]) return 0; |
|
850
|
|
|
|
|
|
|
|
|
851
|
42338
|
100
|
|
|
|
|
if (k == 3) { |
|
852
|
15459
|
100
|
|
|
|
|
r = n % 117; if ((r*833230740) & (r*120676722) & 813764715) return 0; |
|
853
|
2041
|
|
|
|
|
|
r = icbrt(n); |
|
854
|
2041
|
100
|
|
|
|
|
if (root) *root = r; |
|
855
|
2041
|
|
|
|
|
|
return (UV)r*r*r == n; |
|
856
|
|
|
|
|
|
|
} |
|
857
|
|
|
|
|
|
|
|
|
858
|
35090
|
100
|
|
|
|
|
for (msbit = 8 /* k >= 4 */; k >= msbit; msbit <<= 1) ; |
|
859
|
26879
|
|
|
|
|
|
msbit >>= 1; |
|
860
|
26879
|
|
|
|
|
|
r = _est_root(n, k, msbit); |
|
861
|
26879
|
50
|
|
|
|
|
if (root) *root = r; |
|
862
|
26879
|
|
|
|
|
|
return _ipow(r, k, msbit) == n; |
|
863
|
|
|
|
|
|
|
} |
|
864
|
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
#define PORET(base,exp) do { \ |
|
866
|
|
|
|
|
|
|
uint32_t n_ = base; /* In case base uses k or exp uses n */ \ |
|
867
|
|
|
|
|
|
|
k *= exp; \ |
|
868
|
|
|
|
|
|
|
n = n_; \ |
|
869
|
|
|
|
|
|
|
goto poreturn; \ |
|
870
|
|
|
|
|
|
|
} while (0) |
|
871
|
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
/* max power for 64-bit inputs */ |
|
873
|
|
|
|
|
|
|
static const uint8_t _maxpow128[128] = {31,7,0,11,2,7,0,17,3,17,0,13,0,11,0,11,2,11,0,29,0,13,0,11,3,11,0,7,0,7,0,7,5,7,0,13,2,7,0,11,3,7,0,31,0,7,0,11,0,11,0,11,0,11,0,13,3,13,0,13,0,19,0,7,3,7,0,17,2,17,0,11,3,11,0,23,0,17,0,13,0,13,0,13,0,7,0,19,3,19,0,19,0,11,0,11,5,11,0,7,2,13,0,13,3,13,0,7,0,23,0,7,0,7,0,37,0,7,0,11,3,11,0,11,0,13,0,7}; |
|
874
|
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
/* Returns maximal k for c^k = n for k > 1, n > 1. 0 otherwise. */ |
|
876
|
17979
|
|
|
|
|
|
uint32_t powerof_ret(UV n, uint32_t *root) { |
|
877
|
17979
|
|
|
|
|
|
uint32_t r, t, k = 1; |
|
878
|
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
/* SPECIAL: For n = 0 and n = 1, return k=1 with root n. */ |
|
880
|
|
|
|
|
|
|
/* This matches SAGE's .perfect_power(n) method (FLINT chooses k=2). */ |
|
881
|
17979
|
100
|
|
|
|
|
if (n <= 1) { |
|
882
|
1
|
50
|
|
|
|
|
if (root) *root = n; |
|
883
|
1
|
|
|
|
|
|
return 1; |
|
884
|
|
|
|
|
|
|
} |
|
885
|
|
|
|
|
|
|
|
|
886
|
17978
|
100
|
|
|
|
|
if ((n <= 3) || (n == UV_MAX)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
887
|
17947
|
100
|
|
|
|
|
if ((n & (n-1)) == 0) PORET(2,ctz(n)); |
|
|
|
50
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
|
|
889
|
18327
|
100
|
|
|
|
|
while (is_perfect_square_ret(n,&r)) { n = r; k *= 2; } |
|
890
|
18038
|
100
|
|
|
|
|
while (is_power_ret(n, 3, &r)) { n = r; k *= 3; } |
|
891
|
17938
|
100
|
|
|
|
|
while (is_power_ret(n, 5, &r)) { n = r; k *= 5; } |
|
892
|
|
|
|
|
|
|
|
|
893
|
17920
|
100
|
|
|
|
|
if (is_power_ret(n, 7, &r)) PORET(r,7); |
|
894
|
|
|
|
|
|
|
|
|
895
|
19498
|
|
|
|
|
|
if ( !(((n%121)*0x8dd6295a) & 0x2088081) && |
|
896
|
1591
|
|
|
|
|
|
is_power_ret(n, 11, &r) ) PORET(r,11); |
|
897
|
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
/* Reject 78% of inputs as not powers of 13,17,19,... */ |
|
899
|
17907
|
100
|
|
|
|
|
if (_maxpow128[n % 128] < 13) goto poreturn; |
|
900
|
|
|
|
|
|
|
|
|
901
|
3459
|
100
|
|
|
|
|
if (is_power_ret(n, 13, &r)) PORET(r,13); |
|
902
|
3455
|
100
|
|
|
|
|
if (is_power_ret(n, 17, &r)) PORET(r,17); |
|
903
|
|
|
|
|
|
|
|
|
904
|
3448
|
100
|
|
|
|
|
if (n >= 1162261467) { |
|
905
|
41
|
|
|
|
|
|
r = t = 0; |
|
906
|
41
|
|
|
|
|
|
switch (n) { |
|
907
|
0
|
|
|
|
|
|
case UVCONST(1162261467): t=19; r=3; break; |
|
908
|
|
|
|
|
|
|
#if BITS_PER_WORD == 64 |
|
909
|
0
|
|
|
|
|
|
case UVCONST(19073486328125): t=19; r=5; break; |
|
910
|
1
|
|
|
|
|
|
case UVCONST(609359740010496): t=19; r=6; break; |
|
911
|
2
|
|
|
|
|
|
case UVCONST(11398895185373143): t=19; r=7; break; |
|
912
|
1
|
|
|
|
|
|
case UVCONST(10000000000000000000): t=19; r=10;break; |
|
913
|
0
|
|
|
|
|
|
case UVCONST(94143178827): t=23; r=3; break; |
|
914
|
0
|
|
|
|
|
|
case UVCONST(11920928955078125): t=23; r=5; break; |
|
915
|
1
|
|
|
|
|
|
case UVCONST(789730223053602816): t=23; r=6; break; |
|
916
|
0
|
|
|
|
|
|
case UVCONST(68630377364883): t=29; r=3; break; |
|
917
|
1
|
|
|
|
|
|
case UVCONST(617673396283947): t=31; r=3; break; |
|
918
|
0
|
|
|
|
|
|
case UVCONST(450283905890997363): t=37; r=3; break; |
|
919
|
|
|
|
|
|
|
#endif |
|
920
|
35
|
|
|
|
|
|
default: break; |
|
921
|
|
|
|
|
|
|
} |
|
922
|
41
|
100
|
|
|
|
|
if (t != 0) { n = r; k *= t; } |
|
923
|
|
|
|
|
|
|
} |
|
924
|
|
|
|
|
|
|
|
|
925
|
3442
|
|
|
|
|
|
poreturn: |
|
926
|
17947
|
100
|
|
|
|
|
if (k <= 1) return 0; |
|
927
|
512
|
100
|
|
|
|
|
if (root) *root = n; |
|
928
|
512
|
|
|
|
|
|
return k; |
|
929
|
|
|
|
|
|
|
} |
|
930
|
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
|
|
932
|
|
|
|
|
|
|
/******************************************************************************/ |
|
933
|
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
/* Like lcm_ui, but returns 0 if overflow */ |
|
936
|
342
|
|
|
|
|
|
UV lcmsafe(UV x, UV y) { |
|
937
|
342
|
50
|
|
|
|
|
if (x==0 || y==0) return 0; |
|
|
|
50
|
|
|
|
|
|
|
938
|
342
|
|
|
|
|
|
y /= gcd_ui(x,y); |
|
939
|
342
|
100
|
|
|
|
|
if (UV_MAX/x < y) return 0; |
|
940
|
341
|
|
|
|
|
|
return x*y; |
|
941
|
|
|
|
|
|
|
} |
|
942
|
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
|
|
944
|
1310
|
|
|
|
|
|
UV valuation(UV n, UV k) |
|
945
|
|
|
|
|
|
|
{ |
|
946
|
1310
|
|
|
|
|
|
UV v = 0; |
|
947
|
1310
|
|
|
|
|
|
UV kpower = k; |
|
948
|
1310
|
50
|
|
|
|
|
if (k < 2 || n < 2) return 0; |
|
|
|
100
|
|
|
|
|
|
|
949
|
1305
|
100
|
|
|
|
|
if (k == 2) return ctz(n); |
|
|
|
50
|
|
|
|
|
|
|
950
|
786
|
100
|
|
|
|
|
while ( !(n % kpower) ) { |
|
951
|
59
|
|
|
|
|
|
kpower *= k; |
|
952
|
59
|
|
|
|
|
|
v++; |
|
953
|
|
|
|
|
|
|
} |
|
954
|
727
|
|
|
|
|
|
return v; |
|
955
|
|
|
|
|
|
|
} |
|
956
|
|
|
|
|
|
|
/* N => k^s * t => s = valuation_remainder(N, k, &t); */ |
|
957
|
26
|
|
|
|
|
|
UV valuation_remainder(UV n, UV k, UV *r) { |
|
958
|
|
|
|
|
|
|
UV v; |
|
959
|
26
|
50
|
|
|
|
|
if (k <= 1) { v = 0; } |
|
960
|
26
|
50
|
|
|
|
|
else if (k == 2) { v = ctz(n); n >>= v; } |
|
|
|
50
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
else { |
|
962
|
0
|
0
|
|
|
|
|
for (v=0; !(n % k); v++) |
|
963
|
0
|
|
|
|
|
|
n /= k; |
|
964
|
|
|
|
|
|
|
} |
|
965
|
26
|
|
|
|
|
|
*r = n; |
|
966
|
26
|
|
|
|
|
|
return v; |
|
967
|
|
|
|
|
|
|
} |
|
968
|
|
|
|
|
|
|
|
|
969
|
1228
|
|
|
|
|
|
UV logint(UV n, UV b) |
|
970
|
|
|
|
|
|
|
{ |
|
971
|
|
|
|
|
|
|
/* UV e; for (e=0; n; n /= b) e++; return e-1; */ |
|
972
|
1228
|
|
|
|
|
|
UV v, e = 0; |
|
973
|
1228
|
100
|
|
|
|
|
if (b <= 2) |
|
974
|
388
|
50
|
|
|
|
|
return b == 2 ? log2floor(n) : 0; /* b < 2 is invalid */ |
|
|
|
50
|
|
|
|
|
|
|
975
|
840
|
100
|
|
|
|
|
if (b > n) |
|
976
|
16
|
|
|
|
|
|
return 0; |
|
977
|
824
|
50
|
|
|
|
|
if (n > UV_MAX/b) { |
|
978
|
0
|
|
|
|
|
|
n /= b; |
|
979
|
0
|
|
|
|
|
|
e = 1; |
|
980
|
|
|
|
|
|
|
} |
|
981
|
2841
|
100
|
|
|
|
|
for (v = b; v <= n; v *= b) |
|
982
|
2017
|
|
|
|
|
|
e++; |
|
983
|
824
|
|
|
|
|
|
return e; |
|
984
|
|
|
|
|
|
|
} |
|
985
|
|
|
|
|
|
|
|
|
986
|
407
|
|
|
|
|
|
unsigned char* range_issquarefree(UV lo, UV hi) { |
|
987
|
|
|
|
|
|
|
unsigned char* isf; |
|
988
|
407
|
|
|
|
|
|
UV i, p2, range = hi-lo+1, sqrthi = isqrt(hi); |
|
989
|
407
|
50
|
|
|
|
|
if (hi < lo) return 0; |
|
990
|
407
|
|
|
|
|
|
New(0, isf, range, unsigned char); |
|
991
|
407
|
|
|
|
|
|
memset(isf, 1, range); |
|
992
|
407
|
100
|
|
|
|
|
if (lo == 0) isf[0] = 0; |
|
993
|
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
{ /* Sieve multiples of 2^2,3^2,5^2 */ |
|
995
|
407
|
|
|
|
|
|
UV p = 2; |
|
996
|
667
|
100
|
|
|
|
|
while (p < 7 && p <= sqrthi) { |
|
|
|
100
|
|
|
|
|
|
|
997
|
81151
|
100
|
|
|
|
|
for (p2=p*p, i = P_GT_LO(p2, p2, lo); i >= lo && i <= hi; i += p2) |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
998
|
80891
|
|
|
|
|
|
isf[i-lo] = 0; |
|
999
|
260
|
100
|
|
|
|
|
p += 1 + (p > 2); |
|
1000
|
|
|
|
|
|
|
} |
|
1001
|
|
|
|
|
|
|
} |
|
1002
|
407
|
100
|
|
|
|
|
if (sqrthi >= 7) { /* Sieve multiples of higher prime squares */ |
|
1003
|
|
|
|
|
|
|
unsigned char* segment; |
|
1004
|
|
|
|
|
|
|
UV seg_base, seg_low, seg_high; |
|
1005
|
27
|
|
|
|
|
|
void* ctx = start_segment_primes(7, sqrthi, &segment); |
|
1006
|
54
|
100
|
|
|
|
|
while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) { |
|
1007
|
703
|
50
|
|
|
|
|
START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high ) |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1008
|
10555
|
100
|
|
|
|
|
for (p2=p*p, i = P_GT_LO(p2, p2, lo); i >= lo && i <= hi; i += p2) |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1009
|
9918
|
|
|
|
|
|
isf[i-lo] = 0; |
|
1010
|
39
|
|
|
|
|
|
END_DO_FOR_EACH_SIEVE_PRIME |
|
1011
|
|
|
|
|
|
|
} |
|
1012
|
27
|
|
|
|
|
|
end_segment_primes(ctx); |
|
1013
|
|
|
|
|
|
|
} |
|
1014
|
407
|
|
|
|
|
|
return isf; |
|
1015
|
|
|
|
|
|
|
} |
|
1016
|
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
|
|
1018
|
|
|
|
|
|
|
#if BITS_PER_WORD == 32 |
|
1019
|
|
|
|
|
|
|
static const uint32_t _max_ps_n[32] = {0,92681,2343,361,116,53,30,20,14,11,8,7,6,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2}; |
|
1020
|
|
|
|
|
|
|
static const uint32_t _max_ps_calc[9] = {0,0,1624,0,67,44,19,17,9}; |
|
1021
|
|
|
|
|
|
|
#else |
|
1022
|
|
|
|
|
|
|
static const UV _max_ps_n[64] = {0,UVCONST(6074000999),3810777,92681,9839,2190,745,331,175,105,69,49,36,28,22,18,15,13,11,10,9,8,7,6,6,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}; |
|
1023
|
|
|
|
|
|
|
static const uint32_t _max_ps_calc[9] = {0,0,2642245,0,5724,1824,482,288,115}; |
|
1024
|
|
|
|
|
|
|
#endif |
|
1025
|
|
|
|
|
|
|
|
|
1026
|
20983
|
|
|
|
|
|
UV powersum(UV n, UV k) |
|
1027
|
|
|
|
|
|
|
{ |
|
1028
|
|
|
|
|
|
|
UV a, a2, i, sum; |
|
1029
|
|
|
|
|
|
|
|
|
1030
|
20983
|
100
|
|
|
|
|
if (n <= 1 || k == 0) return n; |
|
|
|
100
|
|
|
|
|
|
|
1031
|
12038
|
100
|
|
|
|
|
if (k >= BITS_PER_WORD || n > _max_ps_n[k]) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1032
|
12026
|
100
|
|
|
|
|
if (n == 2) return 1 + (UVCONST(1) << k); |
|
1033
|
|
|
|
|
|
|
|
|
1034
|
8935
|
|
|
|
|
|
a = (n+1)/2 * (n|1); /* (n*(n+1))/2 */ |
|
1035
|
8935
|
|
|
|
|
|
a2 = a*a; |
|
1036
|
8935
|
100
|
|
|
|
|
if (k == 1) return a; |
|
1037
|
8932
|
100
|
|
|
|
|
if (k == 3) return a2; |
|
1038
|
|
|
|
|
|
|
|
|
1039
|
4801
|
100
|
|
|
|
|
if (k <= 8 && n <= _max_ps_calc[k]) { /* Use simple formula if possible */ |
|
|
|
100
|
|
|
|
|
|
|
1040
|
4521
|
100
|
|
|
|
|
if (k == 2) return a * (2*n+1) / 3; |
|
1041
|
2298
|
100
|
|
|
|
|
if (k == 4) return a * (2*n+1) * (3*n*(n+1)-1) / 15; |
|
1042
|
1086
|
100
|
|
|
|
|
if (k == 5) return a2 * (4*a - 1) / 3; |
|
1043
|
551
|
100
|
|
|
|
|
if (k == 6) return a * (2*n+1) * (n*((n*(n*(3*n+6)))-3)+1) / 21; |
|
1044
|
282
|
100
|
|
|
|
|
if (k == 7) return a2 * (6*a2 - 4*a + 1) / 3; |
|
1045
|
121
|
50
|
|
|
|
|
if (k == 8) return a * (2*n+1) * (n*(n*(n*(n*(n*(5*n+15)+5)-15)-1)+9)-3)/45; |
|
1046
|
|
|
|
|
|
|
} |
|
1047
|
|
|
|
|
|
|
|
|
1048
|
280
|
100
|
|
|
|
|
if (k <= 8 && k < n) { |
|
|
|
50
|
|
|
|
|
|
|
1049
|
10
|
|
|
|
|
|
UV r, fac = 1; |
|
1050
|
56
|
100
|
|
|
|
|
for (sum = 0, r = 1; r <= k; r++) { |
|
1051
|
|
|
|
|
|
|
/* sum += factorial(r) * stirling2(k,r) * binomial(n+1,r+1); */ |
|
1052
|
46
|
|
|
|
|
|
sum += fac * stirling2(k,r) * binomial(n+1,r+1);; |
|
1053
|
46
|
|
|
|
|
|
fac *= (r+1); |
|
1054
|
|
|
|
|
|
|
} |
|
1055
|
10
|
|
|
|
|
|
return sum; |
|
1056
|
|
|
|
|
|
|
} |
|
1057
|
|
|
|
|
|
|
|
|
1058
|
270
|
|
|
|
|
|
sum = 1 + (UVCONST(1)<
|
|
1059
|
1261
|
100
|
|
|
|
|
for (i = 3; i <= n; i++) |
|
1060
|
991
|
|
|
|
|
|
sum += ipow(i, k); |
|
1061
|
270
|
|
|
|
|
|
return sum; |
|
1062
|
|
|
|
|
|
|
} |
|
1063
|
|
|
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
|
|
1065
|
3
|
|
|
|
|
|
UV mpu_popcount_string(const char* ptr, uint32_t len) |
|
1066
|
|
|
|
|
|
|
{ |
|
1067
|
3
|
|
|
|
|
|
uint32_t count = 0, i, j, d, v, power, slen, *s, *sptr; |
|
1068
|
|
|
|
|
|
|
|
|
1069
|
3
|
50
|
|
|
|
|
while (len > 0 && (*ptr == '0' || *ptr == '+' || *ptr == '-')) |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1070
|
0
|
|
|
|
|
|
{ ptr++; len--; } |
|
1071
|
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
/* Create s as array of base 10^8 numbers */ |
|
1073
|
3
|
|
|
|
|
|
slen = (len + 7) / 8; |
|
1074
|
3
|
|
|
|
|
|
Newz(0, s, slen, uint32_t); |
|
1075
|
23
|
100
|
|
|
|
|
for (i = 0; i < slen; i++) { /* Chunks of 8 digits */ |
|
1076
|
172
|
100
|
|
|
|
|
for (j = 0, d = 0, power = 1; j < 8 && len > 0; j++, power *= 10) { |
|
|
|
100
|
|
|
|
|
|
|
1077
|
152
|
|
|
|
|
|
v = ptr[--len] - '0'; |
|
1078
|
152
|
50
|
|
|
|
|
if (v > 9) croak("Parameter '%s' must be a single decimal number",ptr); |
|
1079
|
152
|
|
|
|
|
|
d += power * v; |
|
1080
|
|
|
|
|
|
|
} |
|
1081
|
20
|
|
|
|
|
|
s[slen - 1 - i] = d; |
|
1082
|
|
|
|
|
|
|
} |
|
1083
|
|
|
|
|
|
|
/* Repeatedly count and divide by 2 across s */ |
|
1084
|
428
|
100
|
|
|
|
|
while (slen > 1) { |
|
1085
|
425
|
100
|
|
|
|
|
if (s[slen-1] & 1) count++; |
|
1086
|
425
|
|
|
|
|
|
sptr = s; |
|
1087
|
425
|
100
|
|
|
|
|
if (s[0] == 1) { |
|
1088
|
17
|
50
|
|
|
|
|
if (--slen == 0) break; |
|
1089
|
17
|
|
|
|
|
|
*++sptr += 100000000; |
|
1090
|
|
|
|
|
|
|
} |
|
1091
|
2476
|
100
|
|
|
|
|
for (i = 0; i < slen; i++) { |
|
1092
|
2051
|
100
|
|
|
|
|
if ( (i+1) < slen && sptr[i] & 1 ) sptr[i+1] += 100000000; |
|
|
|
100
|
|
|
|
|
|
|
1093
|
2051
|
|
|
|
|
|
s[i] = sptr[i] >> 1; |
|
1094
|
|
|
|
|
|
|
} |
|
1095
|
|
|
|
|
|
|
} |
|
1096
|
|
|
|
|
|
|
/* For final base 10^8 number just do naive popcnt */ |
|
1097
|
83
|
100
|
|
|
|
|
for (d = s[0]; d > 0; d >>= 1) |
|
1098
|
80
|
100
|
|
|
|
|
if (d & 1) |
|
1099
|
38
|
|
|
|
|
|
count++; |
|
1100
|
3
|
|
|
|
|
|
Safefree(s); |
|
1101
|
3
|
|
|
|
|
|
return count; |
|
1102
|
|
|
|
|
|
|
} |
|
1103
|
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
/* How many times does 2 divide n? */ |
|
1106
|
|
|
|
|
|
|
#define padic2(n) ctz(n) |
|
1107
|
|
|
|
|
|
|
#define IS_MOD8_3OR5(x) (((x)&7)==3 || ((x)&7)==5) |
|
1108
|
|
|
|
|
|
|
|
|
1109
|
2913
|
|
|
|
|
|
static int kronecker_uu_sign(UV a, UV b, int s) { |
|
1110
|
11126
|
100
|
|
|
|
|
while (a) { |
|
1111
|
8213
|
50
|
|
|
|
|
int r = padic2(a); |
|
1112
|
8213
|
100
|
|
|
|
|
if (r) { |
|
1113
|
3164
|
100
|
|
|
|
|
if ((r&1) && IS_MOD8_3OR5(b)) s = -s; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1114
|
3164
|
|
|
|
|
|
a >>= r; |
|
1115
|
|
|
|
|
|
|
} |
|
1116
|
8213
|
100
|
|
|
|
|
if (a & b & 2) s = -s; |
|
1117
|
8213
|
|
|
|
|
|
{ UV t = b % a; b = a; a = t; } |
|
1118
|
|
|
|
|
|
|
} |
|
1119
|
2913
|
100
|
|
|
|
|
return (b == 1) ? s : 0; |
|
1120
|
|
|
|
|
|
|
} |
|
1121
|
|
|
|
|
|
|
|
|
1122
|
2924
|
|
|
|
|
|
int kronecker_uu(UV a, UV b) { |
|
1123
|
|
|
|
|
|
|
int r, s; |
|
1124
|
2924
|
100
|
|
|
|
|
if (b & 1) return kronecker_uu_sign(a, b, 1); |
|
1125
|
30
|
100
|
|
|
|
|
if (!(a&1)) return 0; |
|
1126
|
6
|
|
|
|
|
|
s = 1; |
|
1127
|
6
|
100
|
|
|
|
|
r = padic2(b); |
|
1128
|
6
|
50
|
|
|
|
|
if (r) { |
|
1129
|
6
|
100
|
|
|
|
|
if ((r&1) && IS_MOD8_3OR5(a)) s = -s; |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1130
|
6
|
|
|
|
|
|
b >>= r; |
|
1131
|
|
|
|
|
|
|
} |
|
1132
|
6
|
|
|
|
|
|
return kronecker_uu_sign(a, b, s); |
|
1133
|
|
|
|
|
|
|
} |
|
1134
|
|
|
|
|
|
|
|
|
1135
|
43
|
|
|
|
|
|
int kronecker_su(IV a, UV b) { |
|
1136
|
|
|
|
|
|
|
int r, s; |
|
1137
|
|
|
|
|
|
|
UV rem; |
|
1138
|
43
|
100
|
|
|
|
|
if (a >= 0) return kronecker_uu(a, b); |
|
1139
|
15
|
100
|
|
|
|
|
if (b == 0) return (a == 1 || a == -1) ? 1 : 0; |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1140
|
13
|
|
|
|
|
|
s = 1; |
|
1141
|
13
|
50
|
|
|
|
|
r = padic2(b); |
|
1142
|
13
|
100
|
|
|
|
|
if (r) { |
|
1143
|
2
|
50
|
|
|
|
|
if (!(a&1)) return 0; |
|
1144
|
2
|
50
|
|
|
|
|
if ((r&1) && IS_MOD8_3OR5(a)) s = -s; |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1145
|
2
|
|
|
|
|
|
b >>= r; |
|
1146
|
|
|
|
|
|
|
} |
|
1147
|
13
|
|
|
|
|
|
rem = (-a) % b; |
|
1148
|
13
|
100
|
|
|
|
|
a = (rem == 0) ? 0 : b-rem; |
|
1149
|
13
|
|
|
|
|
|
return kronecker_uu_sign(a, b, s); |
|
1150
|
|
|
|
|
|
|
} |
|
1151
|
|
|
|
|
|
|
|
|
1152
|
0
|
|
|
|
|
|
int kronecker_ss(IV a, IV b) { |
|
1153
|
0
|
0
|
|
|
|
|
if (a >= 0 && b >= 0) |
|
|
|
0
|
|
|
|
|
|
|
1154
|
0
|
0
|
|
|
|
|
return (b & 1) ? kronecker_uu_sign(a, b, 1) : kronecker_uu(a,b); |
|
1155
|
0
|
0
|
|
|
|
|
if (b >= 0) |
|
1156
|
0
|
|
|
|
|
|
return kronecker_su(a, b); |
|
1157
|
0
|
0
|
|
|
|
|
return kronecker_su(a, -b) * ((a < 0) ? -1 : 1); |
|
1158
|
|
|
|
|
|
|
} |
|
1159
|
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
#define MAX_PNPRIM ( (BITS_PER_WORD == 64) ? 15 : 9 ) |
|
1161
|
|
|
|
|
|
|
#define MAX_PRIM ( (BITS_PER_WORD == 64) ? 52 : 28 ) |
|
1162
|
|
|
|
|
|
|
#if BITS_PER_WORD == 64 |
|
1163
|
|
|
|
|
|
|
static const UV _pn_prim[MAX_PNPRIM+1] = |
|
1164
|
|
|
|
|
|
|
{1,2,6,30,210,2310,30030,510510,9699690,223092870, |
|
1165
|
|
|
|
|
|
|
UVCONST(6469693230),UVCONST(200560490130),UVCONST(7420738134810),UVCONST(304250263527210),UVCONST(13082761331670030),UVCONST(614889782588491410)}; |
|
1166
|
|
|
|
|
|
|
static const unsigned char _prim_map[MAX_PRIM+1] = |
|
1167
|
|
|
|
|
|
|
{0,0,1,2,2,3,3,4,4,4,4,5,5,6,6,6,6,7,7,8,8,8,8,9,9,9,9,9,9,10,10,11,11,11,11,11,11,12,12,12,12,13,13,14,14,14,14,15,15,15,15,15,15}; |
|
1168
|
|
|
|
|
|
|
#else |
|
1169
|
|
|
|
|
|
|
static const UV _pn_prim[MAX_PNPRIM+1] = |
|
1170
|
|
|
|
|
|
|
{1,2,6,30,210,2310,30030,510510,9699690,223092870}; |
|
1171
|
|
|
|
|
|
|
static const unsigned char _prim_map[MAX_PRIM+1] = |
|
1172
|
|
|
|
|
|
|
{0,0,1,2,2,3,3,4,4,4,4,5,5,6,6,6,6,7,7,8,8,8,8,9,9,9,9,9,9}; |
|
1173
|
|
|
|
|
|
|
#endif |
|
1174
|
|
|
|
|
|
|
|
|
1175
|
1144
|
|
|
|
|
|
UV pn_primorial(UV n) { |
|
1176
|
1144
|
100
|
|
|
|
|
return (n > MAX_PNPRIM) ? 0 : _pn_prim[n]; |
|
1177
|
|
|
|
|
|
|
} |
|
1178
|
62
|
|
|
|
|
|
UV primorial(UV n) { |
|
1179
|
62
|
100
|
|
|
|
|
return (n > MAX_PRIM) ? 0 : _pn_prim[_prim_map[n]]; |
|
1180
|
|
|
|
|
|
|
} |
|
1181
|
78355
|
|
|
|
|
|
UV factorial(UV n) { |
|
1182
|
78355
|
|
|
|
|
|
UV i, r = 1; |
|
1183
|
78355
|
100
|
|
|
|
|
if (n > (sizeof(UV) <= 4 ? 12 : 20)) return 0; |
|
1184
|
172363
|
100
|
|
|
|
|
for (i = 2; i <= n; i++) |
|
1185
|
94408
|
|
|
|
|
|
r *= i; |
|
1186
|
77955
|
|
|
|
|
|
return r; |
|
1187
|
|
|
|
|
|
|
} |
|
1188
|
178
|
|
|
|
|
|
UV subfactorial(UV n) { |
|
1189
|
178
|
100
|
|
|
|
|
if (n <= 3) return (n ? n-1 : 1); |
|
|
|
100
|
|
|
|
|
|
|
1190
|
157
|
100
|
|
|
|
|
if (n >= (BITS_PER_WORD == 64 ? 21 : 14)) return 0; |
|
1191
|
153
|
100
|
|
|
|
|
return (n * subfactorial(n-1) + ((n & 1) ? -1 : 1)); |
|
1192
|
|
|
|
|
|
|
} |
|
1193
|
|
|
|
|
|
|
|
|
1194
|
10114
|
|
|
|
|
|
UV binomial(UV n, UV k) { /* Thanks to MJD and RosettaCode for ideas */ |
|
1195
|
10114
|
|
|
|
|
|
UV d, g, r = 1; |
|
1196
|
10114
|
100
|
|
|
|
|
if (k == 0) return 1; |
|
1197
|
9927
|
100
|
|
|
|
|
if (k == 1) return n; |
|
1198
|
8636
|
100
|
|
|
|
|
if (k >= n) return (k == n); |
|
1199
|
7558
|
100
|
|
|
|
|
if (k > n/2) k = n-k; |
|
1200
|
52554
|
100
|
|
|
|
|
for (d = 1; d <= k; d++) { |
|
1201
|
45182
|
100
|
|
|
|
|
if (r >= UV_MAX/n) { /* Possible overflow */ |
|
1202
|
|
|
|
|
|
|
UV nr, dr; /* reduced numerator / denominator */ |
|
1203
|
596
|
|
|
|
|
|
g = gcd_ui(n, d); nr = n/g; dr = d/g; |
|
1204
|
596
|
|
|
|
|
|
g = gcd_ui(r, dr); r = r/g; dr = dr/g; |
|
1205
|
596
|
100
|
|
|
|
|
if (r >= UV_MAX/nr) return 0; /* Unavoidable overflow */ |
|
1206
|
410
|
|
|
|
|
|
r *= nr; |
|
1207
|
410
|
|
|
|
|
|
r /= dr; |
|
1208
|
410
|
|
|
|
|
|
n--; |
|
1209
|
|
|
|
|
|
|
} else { |
|
1210
|
44586
|
|
|
|
|
|
r *= n--; |
|
1211
|
44586
|
|
|
|
|
|
r /= d; |
|
1212
|
|
|
|
|
|
|
} |
|
1213
|
|
|
|
|
|
|
} |
|
1214
|
7372
|
|
|
|
|
|
return r; |
|
1215
|
|
|
|
|
|
|
} |
|
1216
|
|
|
|
|
|
|
|
|
1217
|
190
|
|
|
|
|
|
UV stirling3(UV n, UV m) { /* Lah numbers */ |
|
1218
|
|
|
|
|
|
|
UV f1, f2; |
|
1219
|
|
|
|
|
|
|
|
|
1220
|
190
|
50
|
|
|
|
|
if (m == n) return 1; |
|
1221
|
190
|
50
|
|
|
|
|
if (n == 0 || m == 0 || m > n) return 0; |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1222
|
190
|
100
|
|
|
|
|
if (m == 1) return factorial(n); |
|
1223
|
|
|
|
|
|
|
|
|
1224
|
171
|
|
|
|
|
|
f1 = binomial(n, m); |
|
1225
|
171
|
50
|
|
|
|
|
if (f1 == 0) return 0; |
|
1226
|
171
|
|
|
|
|
|
f2 = binomial(n-1, m-1); |
|
1227
|
171
|
50
|
|
|
|
|
if (f2 == 0 || f1 >= UV_MAX/f2) return 0; |
|
|
|
50
|
|
|
|
|
|
|
1228
|
171
|
|
|
|
|
|
f1 *= f2; |
|
1229
|
171
|
|
|
|
|
|
f2 = factorial(n-m); |
|
1230
|
171
|
50
|
|
|
|
|
if (f2 == 0 || f1 >= UV_MAX/f2) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1231
|
166
|
|
|
|
|
|
return f1 * f2; |
|
1232
|
|
|
|
|
|
|
} |
|
1233
|
|
|
|
|
|
|
|
|
1234
|
1285
|
|
|
|
|
|
IV stirling2(UV n, UV m) { |
|
1235
|
|
|
|
|
|
|
UV f; |
|
1236
|
1285
|
|
|
|
|
|
IV j, k, t, s = 0; |
|
1237
|
|
|
|
|
|
|
|
|
1238
|
1285
|
100
|
|
|
|
|
if (m == n) return 1; |
|
1239
|
1261
|
50
|
|
|
|
|
if (n == 0 || m == 0 || m > n) return 0; |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1240
|
1261
|
100
|
|
|
|
|
if (m == 1) return 1; |
|
1241
|
|
|
|
|
|
|
|
|
1242
|
1051
|
100
|
|
|
|
|
if ((f = factorial(m)) == 0) return 0; |
|
1243
|
5699
|
100
|
|
|
|
|
for (j = 1; j <= (IV)m; j++) { |
|
1244
|
4767
|
|
|
|
|
|
t = binomial(m, j); |
|
1245
|
70938
|
100
|
|
|
|
|
for (k = 1; k <= (IV)n; k++) { |
|
1246
|
66244
|
50
|
|
|
|
|
if (t == 0 || j >= IV_MAX/t) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1247
|
66171
|
|
|
|
|
|
t *= j; |
|
1248
|
|
|
|
|
|
|
} |
|
1249
|
4694
|
100
|
|
|
|
|
if ((m-j) & 1) t *= -1; |
|
1250
|
4694
|
|
|
|
|
|
s += t; |
|
1251
|
|
|
|
|
|
|
} |
|
1252
|
932
|
|
|
|
|
|
return s/f; |
|
1253
|
|
|
|
|
|
|
} |
|
1254
|
|
|
|
|
|
|
|
|
1255
|
192
|
|
|
|
|
|
IV stirling1(UV n, UV m) { |
|
1256
|
192
|
|
|
|
|
|
IV k, t, b1, b2, s2, s = 0; |
|
1257
|
|
|
|
|
|
|
|
|
1258
|
192
|
50
|
|
|
|
|
if (m == n) return 1; |
|
1259
|
192
|
50
|
|
|
|
|
if (n == 0 || m == 0 || m > n) return 0; |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1260
|
192
|
100
|
|
|
|
|
if (m == 1) { |
|
1261
|
19
|
|
|
|
|
|
UV f = factorial(n-1); |
|
1262
|
19
|
50
|
|
|
|
|
if (f>(UV)IV_MAX) return 0; |
|
1263
|
19
|
100
|
|
|
|
|
return (n&1) ? ((IV)f) : -((IV)f); |
|
1264
|
|
|
|
|
|
|
} |
|
1265
|
|
|
|
|
|
|
|
|
1266
|
942
|
100
|
|
|
|
|
for (k = 1; k <= (IV)(n-m); k++) { |
|
1267
|
816
|
|
|
|
|
|
b1 = binomial(k + n - 1, n - m + k); |
|
1268
|
816
|
|
|
|
|
|
b2 = binomial(2 * n - m, n - m - k); |
|
1269
|
816
|
|
|
|
|
|
s2 = stirling2(n - m + k, k); |
|
1270
|
816
|
100
|
|
|
|
|
if (b1 == 0 || b2 == 0 || s2 == 0 || b1 > IV_MAX/b2) return 0; |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1271
|
804
|
|
|
|
|
|
t = b1 * b2; |
|
1272
|
804
|
100
|
|
|
|
|
if (s2 > IV_MAX/t) return 0; |
|
1273
|
769
|
|
|
|
|
|
t *= s2; |
|
1274
|
769
|
100
|
|
|
|
|
s += (k & 1) ? -t : t; |
|
1275
|
|
|
|
|
|
|
} |
|
1276
|
126
|
|
|
|
|
|
return s; |
|
1277
|
|
|
|
|
|
|
} |
|
1278
|
|
|
|
|
|
|
|
|
1279
|
24
|
|
|
|
|
|
UV fubini(UV n) { |
|
1280
|
|
|
|
|
|
|
UV k, sum; |
|
1281
|
24
|
100
|
|
|
|
|
if (n == 0) return 1; |
|
1282
|
23
|
100
|
|
|
|
|
if (n >= ((BITS_PER_WORD == 64) ? 16 : 10)) return 0; |
|
1283
|
120
|
100
|
|
|
|
|
for (sum = 1, k = 2; k <= n; k++) |
|
1284
|
105
|
|
|
|
|
|
sum += factorial(k) * stirling2(n, k); |
|
1285
|
15
|
|
|
|
|
|
return sum; |
|
1286
|
|
|
|
|
|
|
} |
|
1287
|
|
|
|
|
|
|
|
|
1288
|
451
|
|
|
|
|
|
UV falling_factorial(UV n, UV m) |
|
1289
|
|
|
|
|
|
|
{ |
|
1290
|
451
|
|
|
|
|
|
UV i, r = n; |
|
1291
|
451
|
100
|
|
|
|
|
if (m == 0) return 1; |
|
1292
|
430
|
100
|
|
|
|
|
if (m > n) return 0; |
|
1293
|
1617
|
100
|
|
|
|
|
for (i = 1; i < m; i++) { |
|
1294
|
1301
|
100
|
|
|
|
|
if (UV_MAX/(n-i) < r) return UV_MAX; /* Overflow */ |
|
1295
|
1297
|
|
|
|
|
|
r *= (n-i); |
|
1296
|
|
|
|
|
|
|
} |
|
1297
|
316
|
|
|
|
|
|
return r; |
|
1298
|
|
|
|
|
|
|
} |
|
1299
|
236
|
|
|
|
|
|
UV rising_factorial(UV n, UV m) |
|
1300
|
|
|
|
|
|
|
{ |
|
1301
|
236
|
100
|
|
|
|
|
if (m == 0) return 1; |
|
1302
|
215
|
50
|
|
|
|
|
if ((m-1) > (UV_MAX-n)) return UV_MAX; /* Overflow */ |
|
1303
|
215
|
|
|
|
|
|
return falling_factorial(n+m-1, m); |
|
1304
|
|
|
|
|
|
|
} |
|
1305
|
|
|
|
|
|
|
|
|
1306
|
110
|
|
|
|
|
|
IV falling_factorial_s(IV n, UV m) |
|
1307
|
|
|
|
|
|
|
{ |
|
1308
|
110
|
50
|
|
|
|
|
UV r = (n>=0) ? falling_factorial(n,m) : rising_factorial(-n,m); |
|
1309
|
110
|
50
|
|
|
|
|
if (r >= IV_MAX) return IV_MAX; /* Overflow */ |
|
1310
|
110
|
50
|
|
|
|
|
return (n < 0 && (m&1)) ? -(IV)r : (IV)r; |
|
|
|
100
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
} |
|
1312
|
110
|
|
|
|
|
|
IV rising_factorial_s(IV n, UV m) |
|
1313
|
|
|
|
|
|
|
{ |
|
1314
|
110
|
50
|
|
|
|
|
UV r = (n>=0) ? rising_factorial(n,m) : falling_factorial(-n,m); |
|
1315
|
110
|
50
|
|
|
|
|
if (r >= IV_MAX) return IV_MAX; /* Overflow */ |
|
1316
|
110
|
50
|
|
|
|
|
return (n < 0 && (m&1)) ? -(IV)r : (IV)r; |
|
|
|
100
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
} |
|
1318
|
|
|
|
|
|
|
|
|
1319
|
|
|
|
|
|
|
/* We should do: |
|
1320
|
|
|
|
|
|
|
* https://oeis.org/wiki/User:Peter_Luschny/ComputationAndAsymptoticsOfBernoulliNumbers#Seidel |
|
1321
|
|
|
|
|
|
|
*/ |
|
1322
|
60
|
|
|
|
|
|
bool bernfrac(IV *num, UV *den, UV n) { |
|
1323
|
60
|
100
|
|
|
|
|
if (n == 1) { *num = 1; *den = 2; return TRUE; } |
|
1324
|
58
|
|
|
|
|
|
*num = 0; *den = 1; |
|
1325
|
58
|
100
|
|
|
|
|
if (n & 1) return TRUE; |
|
1326
|
46
|
|
|
|
|
|
n >>= 1; |
|
1327
|
46
|
|
|
|
|
|
switch (n) { |
|
1328
|
2
|
|
|
|
|
|
case 0: *num = 1; *den = 1; break; |
|
1329
|
2
|
|
|
|
|
|
case 1: *num = 1; *den = 6; break; |
|
1330
|
2
|
|
|
|
|
|
case 2: *num = -1; *den = 30; break; |
|
1331
|
2
|
|
|
|
|
|
case 3: *num = 1; *den = 42; break; |
|
1332
|
2
|
|
|
|
|
|
case 4: *num = -1; *den = 30; break; |
|
1333
|
2
|
|
|
|
|
|
case 5: *num = 5; *den = 66; break; |
|
1334
|
2
|
|
|
|
|
|
case 6: *num = -691; *den = 2730; break; |
|
1335
|
2
|
|
|
|
|
|
case 7: *num = 7; *den = 6; break; |
|
1336
|
2
|
|
|
|
|
|
case 8: *num = -3617; *den = 510; break; |
|
1337
|
2
|
|
|
|
|
|
case 9: *num = 43867; *den = 798; break; |
|
1338
|
2
|
|
|
|
|
|
case 10: *num = -174611; *den = 330; break; |
|
1339
|
2
|
|
|
|
|
|
case 11: *num = 854513; *den = 138; break; |
|
1340
|
2
|
|
|
|
|
|
case 12: *num = -236364091; *den = 2730; break; |
|
1341
|
1
|
|
|
|
|
|
case 13: *num = 8553103; *den = 6; break; |
|
1342
|
19
|
|
|
|
|
|
default: break; |
|
1343
|
|
|
|
|
|
|
} |
|
1344
|
46
|
|
|
|
|
|
return (*num != 0); |
|
1345
|
|
|
|
|
|
|
} |
|
1346
|
|
|
|
|
|
|
|
|
1347
|
773
|
|
|
|
|
|
static void _harmonic_split(UV *n, UV *d, UV a, UV b) { |
|
1348
|
773
|
100
|
|
|
|
|
if (b-a == 1) { |
|
1349
|
118
|
|
|
|
|
|
*n = 1; |
|
1350
|
118
|
|
|
|
|
|
*d = a; |
|
1351
|
655
|
100
|
|
|
|
|
} else if (b-a == 2) { |
|
1352
|
294
|
|
|
|
|
|
*n = a + a + 1; |
|
1353
|
294
|
|
|
|
|
|
*d = a*a + a; |
|
1354
|
|
|
|
|
|
|
} else { |
|
1355
|
361
|
|
|
|
|
|
UV g,p,q,r,s, m = (a + b) >> 1; |
|
1356
|
361
|
|
|
|
|
|
_harmonic_split(&p, &q, a, m); |
|
1357
|
361
|
|
|
|
|
|
_harmonic_split(&r, &s, m, b); |
|
1358
|
361
|
|
|
|
|
|
*n = p*s + q*r; |
|
1359
|
361
|
|
|
|
|
|
*d = q*s; |
|
1360
|
361
|
|
|
|
|
|
g = gcd_ui(*n,*d); |
|
1361
|
361
|
|
|
|
|
|
*n /= g; |
|
1362
|
361
|
|
|
|
|
|
*d /= g; |
|
1363
|
|
|
|
|
|
|
} |
|
1364
|
773
|
|
|
|
|
|
} |
|
1365
|
54
|
|
|
|
|
|
bool harmfrac(UV *num, UV *den, UV n) { |
|
1366
|
54
|
100
|
|
|
|
|
if (n >= BITS_PER_WORD/2) |
|
1367
|
2
|
|
|
|
|
|
return FALSE; |
|
1368
|
|
|
|
|
|
|
|
|
1369
|
52
|
100
|
|
|
|
|
if (n == 0) { |
|
1370
|
1
|
|
|
|
|
|
*num = 0; *den = 1; |
|
1371
|
|
|
|
|
|
|
} else { |
|
1372
|
|
|
|
|
|
|
UV N, D, g; |
|
1373
|
51
|
|
|
|
|
|
_harmonic_split(&N, &D, 1, n+1); |
|
1374
|
51
|
|
|
|
|
|
g = gcd_ui(N, D); |
|
1375
|
51
|
|
|
|
|
|
*num = N/g; |
|
1376
|
51
|
|
|
|
|
|
*den = D/g; |
|
1377
|
|
|
|
|
|
|
} |
|
1378
|
52
|
|
|
|
|
|
return TRUE; |
|
1379
|
|
|
|
|
|
|
} |
|
1380
|
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
|
|
1382
|
32829
|
|
|
|
|
|
bool is_cyclic(UV n) { |
|
1383
|
|
|
|
|
|
|
UV phi, facs[MPU_MAX_FACTORS+1]; |
|
1384
|
|
|
|
|
|
|
int i, nfacs; |
|
1385
|
|
|
|
|
|
|
|
|
1386
|
32829
|
100
|
|
|
|
|
if (n < 4) return (n != 0); |
|
1387
|
|
|
|
|
|
|
|
|
1388
|
|
|
|
|
|
|
/* Fast filters for necessary conditions */ |
|
1389
|
32822
|
100
|
|
|
|
|
if ( !(n & 1) /* 2 only even */ |
|
1390
|
16438
|
100
|
|
|
|
|
|| !(n% 9) || !(n%25) || !(n%49) /* not sq free */ |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1391
|
13733
|
100
|
|
|
|
|
|| !(n%21) || !(n%39) || !(n%55) || !(n%57) || !(n%93) /* q = 1 mod p */ |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1392
|
12639
|
100
|
|
|
|
|
|| !(n%121) || !(n%169) /* not sq free */ |
|
|
|
100
|
|
|
|
|
|
|
1393
|
12489
|
100
|
|
|
|
|
|| !(n%111) || !(n%129) || !(n%155) || !(n%183)) /* q = 1 mod p */ |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1394
|
20547
|
|
|
|
|
|
return 0; |
|
1395
|
|
|
|
|
|
|
|
|
1396
|
12275
|
100
|
|
|
|
|
if (n <= 200) return 1; /* Filters above were sufficient for tiny inputs */ |
|
1397
|
|
|
|
|
|
|
|
|
1398
|
|
|
|
|
|
|
/* return gcd_ui(n, totient(n)) == 1; */ |
|
1399
|
|
|
|
|
|
|
|
|
1400
|
12178
|
|
|
|
|
|
nfacs = factor(n, facs); |
|
1401
|
12178
|
100
|
|
|
|
|
if (nfacs == 1) |
|
1402
|
3466
|
|
|
|
|
|
return 1; /* prime => cyclic */ |
|
1403
|
19823
|
100
|
|
|
|
|
for (i = 1; i < nfacs; i++) |
|
1404
|
11303
|
100
|
|
|
|
|
if (facs[i] == facs[i-1]) |
|
1405
|
192
|
|
|
|
|
|
return 0; /* repeated factor => not cyclic */ |
|
1406
|
28031
|
100
|
|
|
|
|
for (phi = 1, i = 0; i < nfacs; i++) |
|
1407
|
19511
|
|
|
|
|
|
phi *= facs[i]-1; |
|
1408
|
8520
|
|
|
|
|
|
return gcd_ui(n, phi) == 1; /* cyclic <=> coprime with totient */ |
|
1409
|
|
|
|
|
|
|
} |
|
1410
|
|
|
|
|
|
|
|
|
1411
|
20006
|
|
|
|
|
|
bool is_carmichael(UV n) { |
|
1412
|
|
|
|
|
|
|
factored_t nf; |
|
1413
|
|
|
|
|
|
|
uint32_t i; |
|
1414
|
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
/* Small or even is not a Carmichael number */ |
|
1416
|
20006
|
100
|
|
|
|
|
if (n < 561 || !(n&1)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
|
|
1418
|
|
|
|
|
|
|
/* Simple pre-test for square free (odds only) */ |
|
1419
|
9726
|
100
|
|
|
|
|
if (!(n% 9) || !(n%25) || !(n%49) || !(n%121) || !(n%169)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1420
|
1709
|
|
|
|
|
|
return 0; |
|
1421
|
|
|
|
|
|
|
|
|
1422
|
|
|
|
|
|
|
/* Check Korselt's criterion for small divisors */ |
|
1423
|
8017
|
100
|
|
|
|
|
if (!(n% 5) && ((n-1) % 4 != 0)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1424
|
7351
|
100
|
|
|
|
|
if (!(n% 7) && ((n-1) % 6 != 0)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1425
|
6777
|
100
|
|
|
|
|
if (!(n%11) && ((n-1) % 10 != 0)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1426
|
6339
|
100
|
|
|
|
|
if (!(n%13) && ((n-1) % 12 != 0)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1427
|
5990
|
100
|
|
|
|
|
if (!(n%17) && ((n-1) % 16 != 0)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1428
|
5684
|
100
|
|
|
|
|
if (!(n%19) && ((n-1) % 18 != 0)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1429
|
5423
|
100
|
|
|
|
|
if (!(n%23) && ((n-1) % 22 != 0)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1430
|
|
|
|
|
|
|
|
|
1431
|
|
|
|
|
|
|
/* Fast check without having to factor */ |
|
1432
|
5203
|
100
|
|
|
|
|
if (n > 5000000) { |
|
1433
|
6
|
100
|
|
|
|
|
if (!(n%29) && ((n-1) % 28 != 0)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
1434
|
5
|
100
|
|
|
|
|
if (!(n%31) && ((n-1) % 30 != 0)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
1435
|
4
|
100
|
|
|
|
|
if (!(n%37) && ((n-1) % 36 != 0)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
1436
|
3
|
100
|
|
|
|
|
if (!(n%41) && ((n-1) % 40 != 0)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
1437
|
2
|
100
|
|
|
|
|
if (!(n%43) && ((n-1) % 42 != 0)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
1438
|
1
|
50
|
|
|
|
|
if (!is_pseudoprime(n,2)) return 0; |
|
1439
|
|
|
|
|
|
|
} |
|
1440
|
|
|
|
|
|
|
|
|
1441
|
5197
|
|
|
|
|
|
nf = factorint(n); |
|
1442
|
5197
|
100
|
|
|
|
|
if (nf.nfactors < 3) |
|
1443
|
4664
|
|
|
|
|
|
return 0; |
|
1444
|
1330
|
100
|
|
|
|
|
for (i = 0; i < nf.nfactors; i++) { |
|
1445
|
1321
|
50
|
|
|
|
|
if (nf.e[i] > 1 || ((n-1) % (nf.f[i]-1)) != 0) |
|
|
|
100
|
|
|
|
|
|
|
1446
|
524
|
|
|
|
|
|
return 0; |
|
1447
|
|
|
|
|
|
|
} |
|
1448
|
9
|
|
|
|
|
|
return 1; |
|
1449
|
|
|
|
|
|
|
} |
|
1450
|
|
|
|
|
|
|
|
|
1451
|
8230
|
|
|
|
|
|
static bool is_quasi_base(factored_t nf, UV b) { |
|
1452
|
8230
|
|
|
|
|
|
UV p = nf.n-b; |
|
1453
|
|
|
|
|
|
|
uint32_t i; |
|
1454
|
13159
|
100
|
|
|
|
|
for (i = 0; i < nf.nfactors; i++) { |
|
1455
|
13015
|
|
|
|
|
|
UV d = nf.f[i] - b; |
|
1456
|
13015
|
50
|
|
|
|
|
if (d == 0 || (p % d) != 0) |
|
|
|
100
|
|
|
|
|
|
|
1457
|
8086
|
|
|
|
|
|
return 0; |
|
1458
|
|
|
|
|
|
|
} |
|
1459
|
144
|
|
|
|
|
|
return 1; |
|
1460
|
|
|
|
|
|
|
} |
|
1461
|
|
|
|
|
|
|
|
|
1462
|
|
|
|
|
|
|
/* Returns number of bases that pass */ |
|
1463
|
5402
|
|
|
|
|
|
UV is_quasi_carmichael(UV n) { |
|
1464
|
|
|
|
|
|
|
factored_t nf; |
|
1465
|
|
|
|
|
|
|
UV nbases; |
|
1466
|
|
|
|
|
|
|
UV spf, lpf, ndivisors, *divs; |
|
1467
|
|
|
|
|
|
|
uint32_t i; |
|
1468
|
|
|
|
|
|
|
|
|
1469
|
5402
|
100
|
|
|
|
|
if (n < 35) return 0; |
|
1470
|
|
|
|
|
|
|
|
|
1471
|
|
|
|
|
|
|
/* Simple pre-test for square free */ |
|
1472
|
5334
|
100
|
|
|
|
|
if (!(n% 4) || !(n% 9) || !(n%25) || !(n%49) || !(n%121) || !(n%169)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1473
|
2041
|
|
|
|
|
|
return 0; |
|
1474
|
|
|
|
|
|
|
|
|
1475
|
3293
|
|
|
|
|
|
nf = factorint(n); |
|
1476
|
|
|
|
|
|
|
/* Must be composite */ |
|
1477
|
3293
|
100
|
|
|
|
|
if (nf.nfactors < 2) |
|
1478
|
741
|
|
|
|
|
|
return 0; |
|
1479
|
|
|
|
|
|
|
/* Must be square free */ |
|
1480
|
2552
|
100
|
|
|
|
|
if (!factored_is_square_free(nf)) |
|
1481
|
34
|
|
|
|
|
|
return 0; |
|
1482
|
|
|
|
|
|
|
|
|
1483
|
2518
|
|
|
|
|
|
nbases = 0; |
|
1484
|
2518
|
|
|
|
|
|
spf = nf.f[0]; |
|
1485
|
2518
|
|
|
|
|
|
lpf = nf.f[nf.nfactors-1]; |
|
1486
|
|
|
|
|
|
|
|
|
1487
|
|
|
|
|
|
|
/* Algorithm from Hiroaki Yamanouchi, 2015 */ |
|
1488
|
2518
|
100
|
|
|
|
|
if (nf.nfactors == 2) { |
|
1489
|
1448
|
|
|
|
|
|
divs = divisor_list(n / spf - 1, &ndivisors, UV_MAX); |
|
1490
|
5953
|
50
|
|
|
|
|
for (i = 0; i < ndivisors; i++) { |
|
1491
|
5953
|
|
|
|
|
|
UV d = divs[i]; |
|
1492
|
5953
|
|
|
|
|
|
UV k = spf - d; |
|
1493
|
5953
|
100
|
|
|
|
|
if (d >= spf) break; |
|
1494
|
4505
|
100
|
|
|
|
|
if (is_quasi_base(nf, k)) |
|
1495
|
92
|
|
|
|
|
|
nbases++; |
|
1496
|
|
|
|
|
|
|
} |
|
1497
|
|
|
|
|
|
|
} else { |
|
1498
|
1070
|
|
|
|
|
|
divs = divisor_list(lpf * (n / lpf - 1), &ndivisors, UV_MAX); |
|
1499
|
9523
|
100
|
|
|
|
|
for (i = 0; i < ndivisors; i++) { |
|
1500
|
8453
|
|
|
|
|
|
UV d = divs[i]; |
|
1501
|
8453
|
|
|
|
|
|
UV k = lpf - d; |
|
1502
|
8453
|
100
|
|
|
|
|
if (lpf > d && k >= spf) continue; |
|
|
|
100
|
|
|
|
|
|
|
1503
|
4795
|
100
|
|
|
|
|
if (k != 0 && is_quasi_base(nf, k)) |
|
|
|
100
|
|
|
|
|
|
|
1504
|
52
|
|
|
|
|
|
nbases++; |
|
1505
|
|
|
|
|
|
|
} |
|
1506
|
|
|
|
|
|
|
} |
|
1507
|
2518
|
|
|
|
|
|
Safefree(divs); |
|
1508
|
2518
|
|
|
|
|
|
return nbases; |
|
1509
|
|
|
|
|
|
|
} |
|
1510
|
|
|
|
|
|
|
|
|
1511
|
62349
|
|
|
|
|
|
bool is_semiprime(UV n) { |
|
1512
|
|
|
|
|
|
|
UV sp, p, factors[2]; |
|
1513
|
|
|
|
|
|
|
uint32_t n2, n3; |
|
1514
|
|
|
|
|
|
|
|
|
1515
|
62349
|
100
|
|
|
|
|
if (n < 6) return (n == 4); |
|
1516
|
62228
|
100
|
|
|
|
|
if (!(n&1)) return is_prob_prime(n>>1); |
|
1517
|
31839
|
100
|
|
|
|
|
if (!(n%3)) return is_prob_prime(n/3); |
|
1518
|
21494
|
100
|
|
|
|
|
if (!(n%5)) return is_prob_prime(n/5); |
|
1519
|
|
|
|
|
|
|
/* 27% of random inputs left */ |
|
1520
|
17376
|
|
|
|
|
|
n3 = icbrt(n); |
|
1521
|
64342
|
100
|
|
|
|
|
for (sp = 4; sp < 60; sp++) { |
|
1522
|
64326
|
|
|
|
|
|
p = primes_tiny[sp]; |
|
1523
|
64326
|
100
|
|
|
|
|
if (p > n3) |
|
1524
|
12489
|
|
|
|
|
|
break; |
|
1525
|
51837
|
100
|
|
|
|
|
if ((n % p) == 0) |
|
1526
|
4871
|
|
|
|
|
|
return is_prob_prime(n/p); |
|
1527
|
|
|
|
|
|
|
} |
|
1528
|
|
|
|
|
|
|
/* 9.8% of random inputs left */ |
|
1529
|
12505
|
100
|
|
|
|
|
if (is_def_prime(n)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1530
|
4384
|
100
|
|
|
|
|
if (p > n3) return 1; /* past this, n is a composite and larger than p^3 */ |
|
1531
|
|
|
|
|
|
|
/* 4-8% of random inputs left */ |
|
1532
|
|
|
|
|
|
|
|
|
1533
|
8
|
50
|
|
|
|
|
if (is_perfect_square_ret(n,&n2)) /* Fast square check */ |
|
1534
|
0
|
|
|
|
|
|
return is_def_prime(n2); |
|
1535
|
|
|
|
|
|
|
|
|
1536
|
|
|
|
|
|
|
/* Find one factor, check primality of factor and co-factor */ |
|
1537
|
8
|
50
|
|
|
|
|
if (factor_one(n, factors, 0, 0) != 2) return 0; |
|
1538
|
8
|
50
|
|
|
|
|
return (is_def_prime(factors[0]) && is_def_prime(factors[1])); |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1539
|
|
|
|
|
|
|
} |
|
1540
|
17121
|
|
|
|
|
|
bool is_almost_prime(UV k, UV n) { |
|
1541
|
|
|
|
|
|
|
UV p, sp; |
|
1542
|
|
|
|
|
|
|
|
|
1543
|
17121
|
100
|
|
|
|
|
if (k == 0) return (n == 1); |
|
1544
|
17079
|
100
|
|
|
|
|
if (k == 1) return is_prob_prime(n); |
|
1545
|
16027
|
100
|
|
|
|
|
if (k == 2) return is_semiprime(n); |
|
1546
|
|
|
|
|
|
|
|
|
1547
|
14975
|
100
|
|
|
|
|
if ((n >> k) == 0) return 0; /* The smallest k-almost prime is 2^k */ |
|
1548
|
|
|
|
|
|
|
|
|
1549
|
26749
|
100
|
|
|
|
|
while (k > 0 && !(n& 1)) { k--; n >>= 1; } |
|
|
|
100
|
|
|
|
|
|
|
1550
|
18955
|
100
|
|
|
|
|
while (k > 0 && !(n% 3)) { k--; n /= 3; } |
|
|
|
100
|
|
|
|
|
|
|
1551
|
15733
|
100
|
|
|
|
|
while (k > 0 && !(n% 5)) { k--; n /= 5; } |
|
|
|
100
|
|
|
|
|
|
|
1552
|
14711
|
100
|
|
|
|
|
while (k > 0 && !(n% 7)) { k--; n /= 7; } |
|
|
|
100
|
|
|
|
|
|
|
1553
|
12697
|
|
|
|
|
|
p = 11; |
|
1554
|
12697
|
100
|
|
|
|
|
if (k >= 5) { |
|
1555
|
8603
|
50
|
|
|
|
|
for (sp = 5; k > 1 && n > 1 && sp < NPRIMES_TINY-1; sp++) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1556
|
8597
|
|
|
|
|
|
p = primes_tiny[sp]; |
|
1557
|
8597
|
100
|
|
|
|
|
if (n < ipowsafe(p,k)) |
|
1558
|
8595
|
|
|
|
|
|
return 0; |
|
1559
|
2
|
50
|
|
|
|
|
while ((n % p) == 0 && k > 0) |
|
|
|
0
|
|
|
|
|
|
|
1560
|
0
|
|
|
|
|
|
{ k--; n /= p; } |
|
1561
|
|
|
|
|
|
|
} |
|
1562
|
6
|
|
|
|
|
|
p = primes_tiny[sp]; |
|
1563
|
|
|
|
|
|
|
} |
|
1564
|
4102
|
100
|
|
|
|
|
if (k == 0) return (n == 1); |
|
1565
|
3249
|
100
|
|
|
|
|
if (k == 1) return is_prob_prime(n); |
|
1566
|
2708
|
100
|
|
|
|
|
if (k == 2) return is_semiprime(n); |
|
1567
|
1931
|
100
|
|
|
|
|
if (n < ipowsafe(p,k)) return 0; |
|
1568
|
|
|
|
|
|
|
|
|
1569
|
114
|
|
|
|
|
|
return ((UV)prime_bigomega(n) == k); |
|
1570
|
|
|
|
|
|
|
} |
|
1571
|
|
|
|
|
|
|
|
|
1572
|
102
|
|
|
|
|
|
bool is_fundamental(UV n, bool neg) { |
|
1573
|
102
|
|
|
|
|
|
uint32_t r = n & 15; |
|
1574
|
102
|
100
|
|
|
|
|
if (r) { |
|
1575
|
94
|
100
|
|
|
|
|
if (neg) r = 16-r; |
|
1576
|
94
|
100
|
|
|
|
|
if ((r & 3) == 0 && r != 4) return is_square_free(n >> 2); |
|
|
|
100
|
|
|
|
|
|
|
1577
|
82
|
100
|
|
|
|
|
if ((r & 3) == 1) return is_square_free(n); |
|
1578
|
|
|
|
|
|
|
} |
|
1579
|
65
|
|
|
|
|
|
return 0; |
|
1580
|
|
|
|
|
|
|
} |
|
1581
|
|
|
|
|
|
|
|
|
1582
|
|
|
|
|
|
|
|
|
1583
|
|
|
|
|
|
|
|
|
1584
|
993
|
|
|
|
|
|
UV pillai_v(UV n) { |
|
1585
|
|
|
|
|
|
|
UV v, fac; |
|
1586
|
|
|
|
|
|
|
/* if (n == 0) return 0; */ |
|
1587
|
993
|
100
|
|
|
|
|
if (n < 23 || masktab30[n % 30] == 0 || n % 7 == 0) return 0; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1588
|
223
|
|
|
|
|
|
fac = 5040 % n; |
|
1589
|
223
|
50
|
|
|
|
|
if (n < HALF_WORD) { |
|
1590
|
51838
|
100
|
|
|
|
|
for (v = 8; v < n-1 && fac != 0; v++) { |
|
|
|
100
|
|
|
|
|
|
|
1591
|
51700
|
|
|
|
|
|
fac = (fac*v) % n; |
|
1592
|
51700
|
100
|
|
|
|
|
if (fac == n-1 && (n % v) != 1) |
|
|
|
100
|
|
|
|
|
|
|
1593
|
85
|
|
|
|
|
|
return v; |
|
1594
|
|
|
|
|
|
|
} |
|
1595
|
|
|
|
|
|
|
} else { |
|
1596
|
0
|
0
|
|
|
|
|
for (v = 8; v < n-1 && fac != 0; v++) { |
|
|
|
0
|
|
|
|
|
|
|
1597
|
0
|
|
|
|
|
|
fac = mulmod(fac,v,n); |
|
1598
|
0
|
0
|
|
|
|
|
if (fac == n-1 && (n % v) != 1) |
|
|
|
0
|
|
|
|
|
|
|
1599
|
0
|
|
|
|
|
|
return v; |
|
1600
|
|
|
|
|
|
|
} |
|
1601
|
|
|
|
|
|
|
} |
|
1602
|
138
|
|
|
|
|
|
return 0; |
|
1603
|
|
|
|
|
|
|
} |
|
1604
|
|
|
|
|
|
|
|
|
1605
|
|
|
|
|
|
|
|
|
1606
|
|
|
|
|
|
|
#define MOB_TESTP(p) \ |
|
1607
|
|
|
|
|
|
|
{ uint32_t psq = p*p; if (n >= psq && (n % psq) == 0) return 0; } |
|
1608
|
|
|
|
|
|
|
|
|
1609
|
|
|
|
|
|
|
/* mpu 'for (0..255) { $x=moebius($_)+1; $b[$_ >> 4] |= ($x << (2*($_%16))); } say join ",",@b;' */ |
|
1610
|
|
|
|
|
|
|
static const uint32_t _smoebius[16] = {2703565065U,23406865,620863913,1630114197,157354249,2844895525U,2166423889U,363177345,2835441929U,2709852521U,1095049497,92897577,1772687649,162113833,160497957,689538385}; |
|
1611
|
31780
|
|
|
|
|
|
int moebius(UV n) { |
|
1612
|
31780
|
100
|
|
|
|
|
if (n < 256) return (int)((_smoebius[n >> 4] >> (2*(n % 16))) & 3) - 1; |
|
1613
|
|
|
|
|
|
|
|
|
1614
|
25110
|
100
|
|
|
|
|
if (!(n % 4) || !(n % 9) || !(n % 25) || !(n % 49) || !(n %121) || !(n %169)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1615
|
9588
|
|
|
|
|
|
return 0; |
|
1616
|
|
|
|
|
|
|
|
|
1617
|
15522
|
100
|
|
|
|
|
MOB_TESTP(17); MOB_TESTP(19); MOB_TESTP(23); |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1618
|
15377
|
100
|
|
|
|
|
MOB_TESTP(29); MOB_TESTP(31); MOB_TESTP(37); |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1619
|
|
|
|
|
|
|
|
|
1620
|
15323
|
|
|
|
|
|
return factored_moebius(factorint(n)); |
|
1621
|
|
|
|
|
|
|
} |
|
1622
|
|
|
|
|
|
|
|
|
1623
|
|
|
|
|
|
|
#define ISF_TESTP(p) \ |
|
1624
|
|
|
|
|
|
|
{ uint32_t psq = p*p; if (psq > n) return 1; if ((n % psq) == 0) return 0; } |
|
1625
|
|
|
|
|
|
|
|
|
1626
|
|
|
|
|
|
|
static const uint32_t _isf[8] = {3840601326U,1856556782U,3941394158U,2362371810U,3970362990U,3471729898U,4008603310U,3938642668U}; |
|
1627
|
45435
|
|
|
|
|
|
bool is_square_free(UV n) { |
|
1628
|
45435
|
100
|
|
|
|
|
if (n < 256) return (_isf[n >> 5] & (1U << (n % 32))) != 0; |
|
1629
|
|
|
|
|
|
|
|
|
1630
|
9883
|
100
|
|
|
|
|
if (!(n % 4) || !(n % 9) || !(n % 25) || !(n % 49) || !(n %121) || !(n %169)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1631
|
3424
|
|
|
|
|
|
return 0; |
|
1632
|
|
|
|
|
|
|
|
|
1633
|
6459
|
100
|
|
|
|
|
ISF_TESTP(17); ISF_TESTP(19); ISF_TESTP(23); |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1634
|
5089
|
100
|
|
|
|
|
ISF_TESTP(29); ISF_TESTP(31); ISF_TESTP(37); |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1635
|
|
|
|
|
|
|
|
|
1636
|
3335
|
|
|
|
|
|
return factored_is_square_free(factorint(n)); |
|
1637
|
|
|
|
|
|
|
} |
|
1638
|
|
|
|
|
|
|
|
|
1639
|
517
|
|
|
|
|
|
bool is_perfect_number(UV n) { |
|
1640
|
|
|
|
|
|
|
UV v, m; |
|
1641
|
517
|
100
|
|
|
|
|
if (n == 0 || (n & 1)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1642
|
|
|
|
|
|
|
|
|
1643
|
260
|
|
|
|
|
|
v = valuation(n,2); |
|
1644
|
260
|
|
|
|
|
|
m = n >> v; |
|
1645
|
260
|
100
|
|
|
|
|
if (m & (m+1)) return 0; |
|
1646
|
43
|
100
|
|
|
|
|
if ((m >> v) != 1) return 0; |
|
1647
|
12
|
|
|
|
|
|
return is_mersenne_prime(v+1); |
|
1648
|
|
|
|
|
|
|
} |
|
1649
|
|
|
|
|
|
|
|
|
1650
|
20
|
|
|
|
|
|
UV exp_mangoldt(UV n) { |
|
1651
|
|
|
|
|
|
|
UV p; |
|
1652
|
20
|
100
|
|
|
|
|
if (!prime_power(n,&p)) return 1; /* Not a prime power */ |
|
1653
|
14
|
|
|
|
|
|
return p; |
|
1654
|
|
|
|
|
|
|
} |
|
1655
|
|
|
|
|
|
|
|
|
1656
|
|
|
|
|
|
|
/* least quadratic non-residue mod p (p may be composite) */ |
|
1657
|
|
|
|
|
|
|
/* The returned result will always be 0 or a prime */ |
|
1658
|
35
|
|
|
|
|
|
UV qnr(UV n) { |
|
1659
|
|
|
|
|
|
|
UV a; |
|
1660
|
|
|
|
|
|
|
|
|
1661
|
35
|
100
|
|
|
|
|
if (n <= 2) return n; |
|
1662
|
|
|
|
|
|
|
|
|
1663
|
|
|
|
|
|
|
/* If n is not a prime, this may or may not succeed */ |
|
1664
|
32
|
100
|
|
|
|
|
if (kronecker_uu(2,n) == -1) return 2; |
|
1665
|
|
|
|
|
|
|
|
|
1666
|
28
|
100
|
|
|
|
|
if (is_prime(n)) { |
|
1667
|
31
|
50
|
|
|
|
|
for (a = 3; a < n; a += 2) |
|
1668
|
31
|
100
|
|
|
|
|
if (kronecker_uu(a,n) == -1) |
|
1669
|
3
|
|
|
|
|
|
return a; |
|
1670
|
|
|
|
|
|
|
} else { |
|
1671
|
|
|
|
|
|
|
#if 0 /* Not terrible, but does more work than we need. */ |
|
1672
|
|
|
|
|
|
|
for (a = 2; a < n; a = next_prime(a)) |
|
1673
|
|
|
|
|
|
|
if (!sqrtmod(0, a, n)) |
|
1674
|
|
|
|
|
|
|
return a; |
|
1675
|
|
|
|
|
|
|
#endif |
|
1676
|
|
|
|
|
|
|
factored_t nf; |
|
1677
|
|
|
|
|
|
|
uint32_t i; |
|
1678
|
25
|
100
|
|
|
|
|
if (!(n&1)) { /* Check and remove all multiples of 2 */ |
|
1679
|
22
|
50
|
|
|
|
|
int e = ctz(n); |
|
1680
|
22
|
|
|
|
|
|
n >>= e; |
|
1681
|
29
|
100
|
|
|
|
|
if (e >= 2 || n == 1) return 2; |
|
|
|
50
|
|
|
|
|
|
|
1682
|
|
|
|
|
|
|
} |
|
1683
|
7
|
100
|
|
|
|
|
if (!(n % 3) || !(n % 5) || !(n % 11) || !(n % 13) || !(n % 19)) return 2; |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1684
|
2
|
|
|
|
|
|
nf = factorint(n); |
|
1685
|
4
|
50
|
|
|
|
|
for (a = 2; a < n; a = next_prime(a)) { |
|
1686
|
8
|
100
|
|
|
|
|
for (i = 0; i < nf.nfactors; i++) |
|
1687
|
6
|
50
|
|
|
|
|
if (a < nf.f[i] && kronecker_uu(a,nf.f[i]) == -1) |
|
|
|
100
|
|
|
|
|
|
|
1688
|
2
|
|
|
|
|
|
return a; |
|
1689
|
|
|
|
|
|
|
} |
|
1690
|
|
|
|
|
|
|
} |
|
1691
|
0
|
|
|
|
|
|
return 0; |
|
1692
|
|
|
|
|
|
|
} |
|
1693
|
|
|
|
|
|
|
|
|
1694
|
94
|
|
|
|
|
|
bool is_qr(UV a, UV n) { |
|
1695
|
|
|
|
|
|
|
bool res; |
|
1696
|
94
|
50
|
|
|
|
|
if (n == 0) return (a == 1); /* Should return undef */ |
|
1697
|
94
|
100
|
|
|
|
|
if (n <= 2) return 1; |
|
1698
|
88
|
50
|
|
|
|
|
if (a >= n) a %= n; |
|
1699
|
88
|
100
|
|
|
|
|
if (a <= 1) return 1; |
|
1700
|
|
|
|
|
|
|
|
|
1701
|
58
|
100
|
|
|
|
|
if (is_prob_prime(n)) { |
|
1702
|
3
|
|
|
|
|
|
res = (kronecker_uu(a,n) == 1); |
|
1703
|
|
|
|
|
|
|
} else { |
|
1704
|
|
|
|
|
|
|
factored_t nf; |
|
1705
|
|
|
|
|
|
|
uint32_t i; |
|
1706
|
|
|
|
|
|
|
|
|
1707
|
55
|
|
|
|
|
|
nf = factorint(n); |
|
1708
|
135
|
100
|
|
|
|
|
for (i = 0, res = 1; res && i < nf.nfactors; i++) { |
|
|
|
100
|
|
|
|
|
|
|
1709
|
80
|
100
|
|
|
|
|
if (nf.e[i] == 1 && (nf.f[i] == 2 || gcd_ui(a,nf.f[i]) != 1)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1710
|
20
|
|
|
|
|
|
res = 1; |
|
1711
|
60
|
100
|
|
|
|
|
else if (nf.e[i] == 1 || (nf.f[i] != 2 && gcd_ui(a,nf.f[i]) == 1)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1712
|
51
|
|
|
|
|
|
res = (kronecker_uu(a,nf.f[i]) == 1); |
|
1713
|
|
|
|
|
|
|
else { |
|
1714
|
9
|
|
|
|
|
|
res = sqrtmod(0, a, ipow(nf.f[i],nf.e[i])); |
|
1715
|
|
|
|
|
|
|
} |
|
1716
|
|
|
|
|
|
|
} |
|
1717
|
|
|
|
|
|
|
} |
|
1718
|
58
|
|
|
|
|
|
return res; |
|
1719
|
|
|
|
|
|
|
} |
|
1720
|
|
|
|
|
|
|
|
|
1721
|
75
|
|
|
|
|
|
UV znorder(UV a, UV n) { |
|
1722
|
|
|
|
|
|
|
factored_t phif; |
|
1723
|
|
|
|
|
|
|
UV k, phi; |
|
1724
|
|
|
|
|
|
|
uint32_t i; |
|
1725
|
|
|
|
|
|
|
|
|
1726
|
75
|
50
|
|
|
|
|
if (n <= 1) return n; /* znorder(x,0) = 0, znorder(x,1) = 1 */ |
|
1727
|
75
|
100
|
|
|
|
|
if (a <= 1) return a; /* znorder(0,x) = 0, znorder(1,x) = 1 (x > 1) */ |
|
1728
|
72
|
100
|
|
|
|
|
if (gcd_ui(a,n) > 1) return 0; |
|
1729
|
|
|
|
|
|
|
|
|
1730
|
|
|
|
|
|
|
/* Cohen 1.4.3 using Carmichael Lambda */ |
|
1731
|
66
|
|
|
|
|
|
phi = carmichael_lambda(n); |
|
1732
|
66
|
|
|
|
|
|
phif = factorint(phi); |
|
1733
|
66
|
|
|
|
|
|
k = phi; |
|
1734
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
1735
|
66
|
100
|
|
|
|
|
if (n & 1) { |
|
1736
|
60
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
1737
|
60
|
|
|
|
|
|
UV ma = mont_geta(a, n); |
|
1738
|
284
|
100
|
|
|
|
|
for (i = 0; i < phif.nfactors; i++) { |
|
1739
|
224
|
|
|
|
|
|
UV b, a1, ek, pi = phif.f[i], ei = phif.e[i]; |
|
1740
|
224
|
|
|
|
|
|
b = ipow(pi,ei); |
|
1741
|
224
|
|
|
|
|
|
k /= b; |
|
1742
|
224
|
|
|
|
|
|
a1 = mont_powmod(ma, k, n); |
|
1743
|
433
|
100
|
|
|
|
|
for (ek = 0; a1 != mont1 && ek++ <= ei; a1 = mont_powmod(a1, pi, n)) |
|
|
|
50
|
|
|
|
|
|
|
1744
|
209
|
|
|
|
|
|
k *= pi; |
|
1745
|
224
|
50
|
|
|
|
|
if (ek > ei) return 0; |
|
1746
|
|
|
|
|
|
|
} |
|
1747
|
|
|
|
|
|
|
} else |
|
1748
|
|
|
|
|
|
|
#endif |
|
1749
|
13
|
100
|
|
|
|
|
for (i = 0; i < phif.nfactors; i++) { |
|
1750
|
7
|
|
|
|
|
|
UV b, a1, ek, pi = phif.f[i], ei = phif.e[i]; |
|
1751
|
7
|
|
|
|
|
|
b = ipow(pi,ei); |
|
1752
|
7
|
|
|
|
|
|
k /= b; |
|
1753
|
7
|
|
|
|
|
|
a1 = powmod(a, k, n); |
|
1754
|
14
|
100
|
|
|
|
|
for (ek = 0; a1 != 1 && ek++ <= ei; a1 = powmod(a1, pi, n)) |
|
|
|
50
|
|
|
|
|
|
|
1755
|
7
|
|
|
|
|
|
k *= pi; |
|
1756
|
7
|
50
|
|
|
|
|
if (ek > ei) return 0; |
|
1757
|
|
|
|
|
|
|
} |
|
1758
|
66
|
|
|
|
|
|
return k; |
|
1759
|
|
|
|
|
|
|
} |
|
1760
|
|
|
|
|
|
|
|
|
1761
|
28
|
|
|
|
|
|
UV znprimroot(UV n) { |
|
1762
|
|
|
|
|
|
|
factored_t phif; |
|
1763
|
|
|
|
|
|
|
UV phi_div_fac[MPU_MAX_DFACTORS]; |
|
1764
|
|
|
|
|
|
|
UV p, phi, a, psquared; |
|
1765
|
|
|
|
|
|
|
uint32_t i, root; |
|
1766
|
|
|
|
|
|
|
bool isneven, ispow; |
|
1767
|
|
|
|
|
|
|
|
|
1768
|
28
|
100
|
|
|
|
|
if (n <= 4) return (n == 0) ? 0 : n-1; |
|
|
|
50
|
|
|
|
|
|
|
1769
|
24
|
100
|
|
|
|
|
if (n % 4 == 0) return 0; |
|
1770
|
|
|
|
|
|
|
|
|
1771
|
23
|
|
|
|
|
|
isneven = !(n & 1); |
|
1772
|
23
|
100
|
|
|
|
|
if (isneven) n >>= 1; |
|
1773
|
|
|
|
|
|
|
|
|
1774
|
23
|
|
|
|
|
|
ispow = powerof_ret(n,&root) > 1; |
|
1775
|
23
|
100
|
|
|
|
|
p = ispow ? root : n; |
|
1776
|
23
|
100
|
|
|
|
|
if (p == 3 && isneven) return 5; |
|
|
|
100
|
|
|
|
|
|
|
1777
|
22
|
100
|
|
|
|
|
if (!is_prob_prime(p)) return 0; |
|
1778
|
|
|
|
|
|
|
|
|
1779
|
20
|
|
|
|
|
|
phi = p-1; /* p an odd prime */ |
|
1780
|
20
|
100
|
|
|
|
|
psquared = ispow ? p*p : 0; |
|
1781
|
|
|
|
|
|
|
|
|
1782
|
20
|
|
|
|
|
|
phif = factorint(phi); |
|
1783
|
78
|
100
|
|
|
|
|
for (i = 1; i < phif.nfactors; i++) |
|
1784
|
58
|
|
|
|
|
|
phi_div_fac[i] = phi / phif.f[i]; |
|
1785
|
|
|
|
|
|
|
|
|
1786
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
1787
|
|
|
|
|
|
|
{ |
|
1788
|
|
|
|
|
|
|
UV r; |
|
1789
|
20
|
|
|
|
|
|
const uint64_t npi = mont_inverse(p), mont1 = mont_get1(p); |
|
1790
|
918
|
50
|
|
|
|
|
for (a = 2; a < p; a++) { |
|
1791
|
918
|
100
|
|
|
|
|
if (isneven && !(a&1)) continue; |
|
|
|
100
|
|
|
|
|
|
|
1792
|
888
|
100
|
|
|
|
|
if (a == 4 || a == 8 || a == 9) continue; /* Skip some perfect powers */ |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1793
|
858
|
100
|
|
|
|
|
if (kronecker_uu(a, p) != -1) continue; |
|
1794
|
171
|
|
|
|
|
|
r = mont_geta(a, p); |
|
1795
|
298
|
100
|
|
|
|
|
for (i = 1; i < phif.nfactors; i++) |
|
1796
|
278
|
100
|
|
|
|
|
if (mont_powmod(r, phi_div_fac[i], p) == mont1) |
|
1797
|
151
|
|
|
|
|
|
break; |
|
1798
|
171
|
100
|
|
|
|
|
if (i == phif.nfactors) |
|
1799
|
20
|
100
|
|
|
|
|
if (!ispow || powmod(a, phi, psquared) != 1) |
|
|
|
50
|
|
|
|
|
|
|
1800
|
20
|
|
|
|
|
|
return a; |
|
1801
|
|
|
|
|
|
|
} |
|
1802
|
|
|
|
|
|
|
} |
|
1803
|
|
|
|
|
|
|
#else |
|
1804
|
|
|
|
|
|
|
for (a = 2; a < p; a++) { |
|
1805
|
|
|
|
|
|
|
if (isneven && !(a&1)) continue; |
|
1806
|
|
|
|
|
|
|
if (a == 4 || a == 8 || a == 9) continue; /* Skip some perfect powers */ |
|
1807
|
|
|
|
|
|
|
if (kronecker_uu(a, p) != -1) continue; |
|
1808
|
|
|
|
|
|
|
for (i = 1; i < phif.nfactors; i++) |
|
1809
|
|
|
|
|
|
|
if (powmod(a, phi_div_fac[i], p) == 1) |
|
1810
|
|
|
|
|
|
|
break; |
|
1811
|
|
|
|
|
|
|
if (i == phif.nfactors) |
|
1812
|
|
|
|
|
|
|
if (!ispow || powmod(a, phi, psquared) != 1) |
|
1813
|
|
|
|
|
|
|
return a; |
|
1814
|
|
|
|
|
|
|
} |
|
1815
|
|
|
|
|
|
|
#endif |
|
1816
|
0
|
|
|
|
|
|
return 0; |
|
1817
|
|
|
|
|
|
|
} |
|
1818
|
|
|
|
|
|
|
|
|
1819
|
85
|
|
|
|
|
|
bool is_primitive_root(UV a, UV n, bool nprime) { |
|
1820
|
|
|
|
|
|
|
factored_t phif; |
|
1821
|
|
|
|
|
|
|
UV p, phi; |
|
1822
|
|
|
|
|
|
|
uint32_t i; |
|
1823
|
|
|
|
|
|
|
|
|
1824
|
|
|
|
|
|
|
/* Trivial but very slow: return totient(n) == znorder(a,n) */ |
|
1825
|
|
|
|
|
|
|
|
|
1826
|
85
|
100
|
|
|
|
|
if (n <= 1) return n; |
|
1827
|
84
|
100
|
|
|
|
|
if (a >= n) a %= n; |
|
1828
|
84
|
100
|
|
|
|
|
if (a == 0) return (n == 1); |
|
1829
|
83
|
100
|
|
|
|
|
if (a == 1) return (n <= 2); |
|
1830
|
70
|
100
|
|
|
|
|
if (n <= 4) return a == n-1; |
|
1831
|
65
|
100
|
|
|
|
|
if (n % 4 == 0) return 0; |
|
1832
|
|
|
|
|
|
|
|
|
1833
|
64
|
100
|
|
|
|
|
if (!(n&1)) { /* If n is even, */ |
|
1834
|
5
|
50
|
|
|
|
|
if (!(a&1)) return 0; /* 'a' cannot also be even */ |
|
1835
|
5
|
|
|
|
|
|
n >>= 1; /* since 'a' is odd, it is also a root of p^k */ |
|
1836
|
|
|
|
|
|
|
} |
|
1837
|
|
|
|
|
|
|
|
|
1838
|
64
|
100
|
|
|
|
|
if (is_perfect_square(a)) return 0; |
|
1839
|
53
|
50
|
|
|
|
|
if (gcd_ui(a,n) != 1) return 0; |
|
1840
|
|
|
|
|
|
|
|
|
1841
|
53
|
100
|
|
|
|
|
if (!nprime) { |
|
1842
|
25
|
|
|
|
|
|
UV k = prime_power(n, &p); |
|
1843
|
25
|
100
|
|
|
|
|
if (!k) return 0; /* Not a prime power */ |
|
1844
|
23
|
|
|
|
|
|
n = p; |
|
1845
|
|
|
|
|
|
|
/* Check if a isn't a root for a power, only two known <= 10^16 */ |
|
1846
|
23
|
100
|
|
|
|
|
if (k > 1 && powmod(a, p-1, p*p) == 1) return 0; |
|
|
|
50
|
|
|
|
|
|
|
1847
|
|
|
|
|
|
|
} |
|
1848
|
51
|
100
|
|
|
|
|
if (kronecker_uu(a,n) != -1) return 0; |
|
1849
|
41
|
|
|
|
|
|
phi = n-1; |
|
1850
|
|
|
|
|
|
|
|
|
1851
|
|
|
|
|
|
|
/* a^x can be a primitive root only if gcd(x,phi) = 1. */ |
|
1852
|
|
|
|
|
|
|
/* Checking powerof(a) will typically take more time than it saves. */ |
|
1853
|
|
|
|
|
|
|
/* We already checked 'a' not a perfect square */ |
|
1854
|
41
|
100
|
|
|
|
|
if (is_power(a,3) && gcd_ui(3,phi) != 1) return 0; |
|
|
|
50
|
|
|
|
|
|
|
1855
|
|
|
|
|
|
|
|
|
1856
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
1857
|
41
|
50
|
|
|
|
|
if (n & 1) { |
|
1858
|
41
|
|
|
|
|
|
const uint64_t npi = mont_inverse(n), mont1 = mont_get1(n); |
|
1859
|
41
|
|
|
|
|
|
a = mont_geta(a, n); |
|
1860
|
|
|
|
|
|
|
/* Quick check for small factors before full factor */ |
|
1861
|
41
|
50
|
|
|
|
|
if ((phi % 2) == 0 && mont_powmod(a, phi/2, n) == mont1) return 0; |
|
|
|
50
|
|
|
|
|
|
|
1862
|
41
|
100
|
|
|
|
|
if ((phi % 3) == 0 && mont_powmod(a, phi/3, n) == mont1) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1863
|
36
|
100
|
|
|
|
|
if ((phi % 5) == 0 && mont_powmod(a, phi/5, n) == mont1) return 0; |
|
|
|
100
|
|
|
|
|
|
|
1864
|
34
|
|
|
|
|
|
phif = factorint(phi); |
|
1865
|
135
|
100
|
|
|
|
|
for (i = 0; i < phif.nfactors; i++) |
|
1866
|
102
|
100
|
|
|
|
|
if (phif.f[i] > 5 && mont_powmod(a, phi/phif.f[i], n) == mont1) |
|
|
|
100
|
|
|
|
|
|
|
1867
|
1
|
|
|
|
|
|
return 0; |
|
1868
|
|
|
|
|
|
|
} else |
|
1869
|
|
|
|
|
|
|
#endif |
|
1870
|
|
|
|
|
|
|
{ |
|
1871
|
|
|
|
|
|
|
/* Quick check for small factors before full factor */ |
|
1872
|
0
|
0
|
|
|
|
|
if ((phi % 2) == 0 && powmod(a, phi/2, n) == 1) return 0; |
|
|
|
0
|
|
|
|
|
|
|
1873
|
0
|
0
|
|
|
|
|
if ((phi % 3) == 0 && powmod(a, phi/3, n) == 1) return 0; |
|
|
|
0
|
|
|
|
|
|
|
1874
|
0
|
0
|
|
|
|
|
if ((phi % 5) == 0 && powmod(a, phi/5, n) == 1) return 0; |
|
|
|
0
|
|
|
|
|
|
|
1875
|
|
|
|
|
|
|
/* Complete factor and check each one not found above. */ |
|
1876
|
0
|
|
|
|
|
|
phif = factorint(phi); |
|
1877
|
0
|
0
|
|
|
|
|
for (i = 0; i < phif.nfactors; i++) |
|
1878
|
0
|
0
|
|
|
|
|
if (phif.f[i] > 5 && powmod(a, phi/phif.f[i], n) == 1) |
|
|
|
0
|
|
|
|
|
|
|
1879
|
0
|
|
|
|
|
|
return 0; |
|
1880
|
|
|
|
|
|
|
} |
|
1881
|
33
|
|
|
|
|
|
return 1; |
|
1882
|
|
|
|
|
|
|
} |
|
1883
|
|
|
|
|
|
|
|
|
1884
|
9631
|
|
|
|
|
|
IV gcdext(IV a, IV b, IV* u, IV* v, IV* cs, IV* ct) { |
|
1885
|
9631
|
|
|
|
|
|
IV s = 0; IV olds = 1; |
|
1886
|
9631
|
|
|
|
|
|
IV t = 1; IV oldt = 0; |
|
1887
|
9631
|
|
|
|
|
|
IV r = b; IV oldr = a; |
|
1888
|
9631
|
100
|
|
|
|
|
if (a == 0 && b == 0) { olds = 0; t = 0; } |
|
|
|
100
|
|
|
|
|
|
|
1889
|
32912
|
100
|
|
|
|
|
while (r != 0) { |
|
1890
|
23281
|
|
|
|
|
|
IV quot = oldr / r; |
|
1891
|
23281
|
|
|
|
|
|
{ IV tmp = r; r = oldr - quot * r; oldr = tmp; } |
|
1892
|
23281
|
|
|
|
|
|
{ IV tmp = s; s = olds - quot * s; olds = tmp; } |
|
1893
|
23281
|
|
|
|
|
|
{ IV tmp = t; t = oldt - quot * t; oldt = tmp; } |
|
1894
|
|
|
|
|
|
|
} |
|
1895
|
9631
|
100
|
|
|
|
|
if (oldr < 0) /* correct sign */ |
|
1896
|
4
|
|
|
|
|
|
{ oldr = -oldr; olds = -olds; oldt = -oldt; } |
|
1897
|
9631
|
50
|
|
|
|
|
if (u != 0) *u = olds; |
|
1898
|
9631
|
100
|
|
|
|
|
if (v != 0) *v = oldt; |
|
1899
|
9631
|
100
|
|
|
|
|
if (cs != 0) *cs = s; |
|
1900
|
9631
|
100
|
|
|
|
|
if (ct != 0) *ct = t; |
|
1901
|
9631
|
|
|
|
|
|
return oldr; |
|
1902
|
|
|
|
|
|
|
} |
|
1903
|
|
|
|
|
|
|
|
|
1904
|
|
|
|
|
|
|
/* Calculate 1/a mod n. */ |
|
1905
|
52385
|
|
|
|
|
|
UV modinverse(UV a, UV n) { |
|
1906
|
52385
|
|
|
|
|
|
IV t = 0; UV nt = 1; |
|
1907
|
52385
|
|
|
|
|
|
UV r = n; UV nr = a; |
|
1908
|
163565
|
100
|
|
|
|
|
while (nr != 0) { |
|
1909
|
111180
|
|
|
|
|
|
UV quot = r / nr; |
|
1910
|
111180
|
|
|
|
|
|
{ UV tmp = nt; nt = t - quot*nt; t = tmp; } |
|
1911
|
111180
|
|
|
|
|
|
{ UV tmp = nr; nr = r - quot*nr; r = tmp; } |
|
1912
|
|
|
|
|
|
|
} |
|
1913
|
52385
|
100
|
|
|
|
|
if (r > 1) return 0; /* No inverse */ |
|
1914
|
45580
|
100
|
|
|
|
|
if (t < 0) t += n; |
|
1915
|
45580
|
|
|
|
|
|
return t; |
|
1916
|
|
|
|
|
|
|
} |
|
1917
|
|
|
|
|
|
|
|
|
1918
|
25043
|
|
|
|
|
|
UV divmod(UV a, UV b, UV n) { /* a / b mod n */ |
|
1919
|
25043
|
|
|
|
|
|
UV binv = modinverse(b, n); |
|
1920
|
25043
|
100
|
|
|
|
|
if (binv == 0) return 0; |
|
1921
|
24978
|
|
|
|
|
|
return mulmod(a, binv, n); |
|
1922
|
|
|
|
|
|
|
} |
|
1923
|
71
|
|
|
|
|
|
UV gcddivmod(UV a, UV b, UV n) { |
|
1924
|
71
|
|
|
|
|
|
UV g = gcd_ui(a,b); |
|
1925
|
71
|
|
|
|
|
|
UV binv = modinverse(b/g, n); |
|
1926
|
71
|
50
|
|
|
|
|
if (binv == 0) return 0; |
|
1927
|
71
|
|
|
|
|
|
return mulmod(a/g, binv, n); |
|
1928
|
|
|
|
|
|
|
} |
|
1929
|
|
|
|
|
|
|
|
|
1930
|
|
|
|
|
|
|
/* In C89, the division and modulo operators are implementation-defined |
|
1931
|
|
|
|
|
|
|
* for negative inputs. C99 fixed this. */ |
|
1932
|
|
|
|
|
|
|
#if __STDC_VERSION__ >= 199901L |
|
1933
|
|
|
|
|
|
|
#define _tdivrem(q,r, D,d) q = D/d, r = D % d |
|
1934
|
|
|
|
|
|
|
#else |
|
1935
|
|
|
|
|
|
|
#define _tdivrem(q,r, D,d) \ |
|
1936
|
|
|
|
|
|
|
q = ((D>=0) ? ( (d>=0) ? D/d : -(D/-d) ) \ |
|
1937
|
|
|
|
|
|
|
: ( (d>=0) ? -(-D/d) : (-D/-d) ) ), \ |
|
1938
|
|
|
|
|
|
|
r = D - d*q |
|
1939
|
|
|
|
|
|
|
#endif |
|
1940
|
|
|
|
|
|
|
|
|
1941
|
15
|
|
|
|
|
|
IV tdivrem(IV *Q, IV *R, IV D, IV d) { |
|
1942
|
|
|
|
|
|
|
IV q,r; |
|
1943
|
15
|
|
|
|
|
|
_tdivrem(q,r,D,d); |
|
1944
|
15
|
50
|
|
|
|
|
if (Q) *Q=q; |
|
1945
|
15
|
50
|
|
|
|
|
if (R) *R=r; |
|
1946
|
15
|
|
|
|
|
|
return r; |
|
1947
|
|
|
|
|
|
|
} |
|
1948
|
21
|
|
|
|
|
|
IV fdivrem(IV *Q, IV *R, IV D, IV d) { |
|
1949
|
|
|
|
|
|
|
IV q,r; |
|
1950
|
21
|
|
|
|
|
|
_tdivrem(q,r,D,d); |
|
1951
|
21
|
100
|
|
|
|
|
if ((r > 0 && d < 0) || (r < 0 && d > 0)) { q--; r += d; } |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1952
|
21
|
50
|
|
|
|
|
if (Q) *Q=q; |
|
1953
|
21
|
50
|
|
|
|
|
if (R) *R=r; |
|
1954
|
21
|
|
|
|
|
|
return r; |
|
1955
|
|
|
|
|
|
|
} |
|
1956
|
18
|
|
|
|
|
|
IV cdivrem(IV *Q, IV *R, IV D, IV d) { |
|
1957
|
|
|
|
|
|
|
IV q,r; |
|
1958
|
18
|
|
|
|
|
|
_tdivrem(q,r,D,d); |
|
1959
|
18
|
100
|
|
|
|
|
if (r != 0 && ((D >= 0) == (d >= 0))) { q++; r -= d; } |
|
|
|
100
|
|
|
|
|
|
|
1960
|
18
|
50
|
|
|
|
|
if (Q) *Q=q; |
|
1961
|
18
|
50
|
|
|
|
|
if (R) *R=r; |
|
1962
|
18
|
|
|
|
|
|
return r; |
|
1963
|
|
|
|
|
|
|
} |
|
1964
|
18
|
|
|
|
|
|
IV edivrem(IV *Q, IV *R, IV D, IV d) { |
|
1965
|
|
|
|
|
|
|
IV q,r; |
|
1966
|
18
|
|
|
|
|
|
_tdivrem(q,r,D,d); |
|
1967
|
18
|
100
|
|
|
|
|
if (r < 0) { |
|
1968
|
13
|
100
|
|
|
|
|
if (d > 0) { q--; r += d; } |
|
1969
|
5
|
|
|
|
|
|
else { q++; r -= d; } |
|
1970
|
|
|
|
|
|
|
} |
|
1971
|
18
|
50
|
|
|
|
|
if (Q) *Q=q; |
|
1972
|
18
|
50
|
|
|
|
|
if (R) *R=r; |
|
1973
|
18
|
|
|
|
|
|
return r; |
|
1974
|
|
|
|
|
|
|
} |
|
1975
|
|
|
|
|
|
|
|
|
1976
|
26528
|
|
|
|
|
|
UV ivmod(IV a, UV n) { /* a mod n with signed a (0 <= r < n) */ |
|
1977
|
26528
|
50
|
|
|
|
|
if (n <= 1) return 0; |
|
1978
|
26528
|
100
|
|
|
|
|
if (a >= 0) { |
|
1979
|
28
|
|
|
|
|
|
return (UV)(a) % n; |
|
1980
|
|
|
|
|
|
|
} else { |
|
1981
|
26500
|
|
|
|
|
|
UV r = (UV)(-a) % n; |
|
1982
|
26500
|
100
|
|
|
|
|
return (r == 0) ? 0 : n-r; |
|
1983
|
|
|
|
|
|
|
} |
|
1984
|
|
|
|
|
|
|
} |
|
1985
|
|
|
|
|
|
|
|
|
1986
|
|
|
|
|
|
|
#if 0 |
|
1987
|
|
|
|
|
|
|
int is_regular(UV a, UV n) { /* there exists an x s.t. a^2*x = a mod n */ |
|
1988
|
|
|
|
|
|
|
UV d; |
|
1989
|
|
|
|
|
|
|
if (a == 0) return 1; |
|
1990
|
|
|
|
|
|
|
d = gcd_ui(a, n); |
|
1991
|
|
|
|
|
|
|
return ( (d % n) == 0 && gcd_ui(d, n/d) == 1); |
|
1992
|
|
|
|
|
|
|
} |
|
1993
|
|
|
|
|
|
|
#endif |
|
1994
|
|
|
|
|
|
|
|
|
1995
|
|
|
|
|
|
|
|
|
1996
|
|
|
|
|
|
|
/******************************************************************************/ |
|
1997
|
|
|
|
|
|
|
/* N! MOD M */ |
|
1998
|
|
|
|
|
|
|
/******************************************************************************/ |
|
1999
|
|
|
|
|
|
|
|
|
2000
|
379
|
|
|
|
|
|
static UV _powersin(UV p, UV d) { |
|
2001
|
379
|
|
|
|
|
|
UV td = d/p, e = td; |
|
2002
|
890
|
100
|
|
|
|
|
do { td/=p; e += td; } while (td > 0); |
|
2003
|
379
|
|
|
|
|
|
return e; |
|
2004
|
|
|
|
|
|
|
} |
|
2005
|
|
|
|
|
|
|
|
|
2006
|
225
|
|
|
|
|
|
static UV _facmod(UV n, UV m) { |
|
2007
|
225
|
|
|
|
|
|
UV i, res = 1; |
|
2008
|
|
|
|
|
|
|
|
|
2009
|
225
|
50
|
|
|
|
|
if (n < 1000) { |
|
2010
|
|
|
|
|
|
|
|
|
2011
|
2031
|
100
|
|
|
|
|
for (i = 2; i <= n && res != 0; i++) |
|
|
|
100
|
|
|
|
|
|
|
2012
|
1806
|
|
|
|
|
|
res = mulmod(res,i,m); |
|
2013
|
|
|
|
|
|
|
|
|
2014
|
|
|
|
|
|
|
} else { |
|
2015
|
|
|
|
|
|
|
|
|
2016
|
|
|
|
|
|
|
unsigned char* segment; |
|
2017
|
|
|
|
|
|
|
UV seg_base, seg_low, seg_high; |
|
2018
|
0
|
|
|
|
|
|
UV sqn = isqrt(n), nsqn = n/sqn, j = sqn, nlo = 0, nhi = 0, s1 = 1; |
|
2019
|
0
|
|
|
|
|
|
void* ctx = start_segment_primes(7, n, &segment); |
|
2020
|
|
|
|
|
|
|
|
|
2021
|
0
|
0
|
|
|
|
|
for (i = 1; i <= 3; i++) { /* Handle 2,3,5 assume n>=25*/ |
|
2022
|
0
|
|
|
|
|
|
UV p = primes_tiny[i]; |
|
2023
|
0
|
|
|
|
|
|
res = mulmod(res, powmod(p,_powersin(p, n),m), m); |
|
2024
|
|
|
|
|
|
|
} |
|
2025
|
0
|
0
|
|
|
|
|
while (res!=0 && next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) { |
|
|
|
0
|
|
|
|
|
|
|
2026
|
0
|
0
|
|
|
|
|
START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high ) |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2027
|
0
|
0
|
|
|
|
|
if (p <= nsqn) { |
|
2028
|
0
|
|
|
|
|
|
res = mulmod(res, powmod(p,_powersin(p,n),m), m); |
|
2029
|
|
|
|
|
|
|
} else { |
|
2030
|
0
|
0
|
|
|
|
|
while (p > nhi) { |
|
2031
|
0
|
|
|
|
|
|
res = mulmod(res, powmod(s1,j,m), m); |
|
2032
|
0
|
|
|
|
|
|
s1 = 1; |
|
2033
|
0
|
|
|
|
|
|
j--; |
|
2034
|
0
|
|
|
|
|
|
nlo = n/(j+1)+1; |
|
2035
|
0
|
|
|
|
|
|
nhi = n/j; |
|
2036
|
|
|
|
|
|
|
} |
|
2037
|
0
|
0
|
|
|
|
|
if (p >= nlo) |
|
2038
|
0
|
|
|
|
|
|
s1 = mulmod(s1, p, m); |
|
2039
|
|
|
|
|
|
|
} |
|
2040
|
0
|
0
|
|
|
|
|
if (res == 0) break; |
|
2041
|
0
|
|
|
|
|
|
END_DO_FOR_EACH_SIEVE_PRIME |
|
2042
|
|
|
|
|
|
|
} |
|
2043
|
0
|
|
|
|
|
|
end_segment_primes(ctx); |
|
2044
|
0
|
|
|
|
|
|
res = mulmod(res, s1, m); |
|
2045
|
|
|
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
} |
|
2047
|
|
|
|
|
|
|
|
|
2048
|
225
|
|
|
|
|
|
return res; |
|
2049
|
|
|
|
|
|
|
} |
|
2050
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
2051
|
198
|
|
|
|
|
|
static UV _facmod_mont(UV n, UV m) { |
|
2052
|
198
|
|
|
|
|
|
const uint64_t npi = mont_inverse(m), mont1 = mont_get1(m); |
|
2053
|
198
|
|
|
|
|
|
uint64_t monti = mont1; |
|
2054
|
198
|
|
|
|
|
|
UV i, res = mont1; |
|
2055
|
|
|
|
|
|
|
|
|
2056
|
198
|
100
|
|
|
|
|
if (n < 1000) { |
|
2057
|
|
|
|
|
|
|
|
|
2058
|
1828
|
100
|
|
|
|
|
for (i = 2; i <= n && res != 0; i++) { |
|
|
|
100
|
|
|
|
|
|
|
2059
|
1632
|
|
|
|
|
|
monti = addmod(monti,mont1,m); |
|
2060
|
1632
|
50
|
|
|
|
|
res = mont_mulmod(res,monti,m); |
|
2061
|
|
|
|
|
|
|
} |
|
2062
|
|
|
|
|
|
|
|
|
2063
|
|
|
|
|
|
|
} else { |
|
2064
|
|
|
|
|
|
|
|
|
2065
|
|
|
|
|
|
|
unsigned char* segment; |
|
2066
|
|
|
|
|
|
|
UV seg_base, seg_low, seg_high; |
|
2067
|
2
|
|
|
|
|
|
UV sqn = isqrt(n), nsqn = n/sqn, j = sqn, nlo = 0, nhi = 0; |
|
2068
|
2
|
|
|
|
|
|
UV s1 = mont1; |
|
2069
|
2
|
|
|
|
|
|
void* ctx = start_segment_primes(7, n, &segment); |
|
2070
|
|
|
|
|
|
|
|
|
2071
|
8
|
100
|
|
|
|
|
for (i = 1; i <= 3; i++) { /* Handle 2,3,5 assume n>=25*/ |
|
2072
|
6
|
|
|
|
|
|
UV p = primes_tiny[i]; |
|
2073
|
6
|
|
|
|
|
|
UV mp = mont_geta(p,m); |
|
2074
|
6
|
50
|
|
|
|
|
res = mont_mulmod(res, mont_powmod(mp,_powersin(p,n),m), m); |
|
2075
|
|
|
|
|
|
|
} |
|
2076
|
9
|
50
|
|
|
|
|
while (res!=0 && next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) { |
|
|
|
100
|
|
|
|
|
|
|
2077
|
374690
|
50
|
|
|
|
|
START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high ) |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
2078
|
353640
|
|
|
|
|
|
UV mp = mont_geta(p,m); |
|
2079
|
353640
|
100
|
|
|
|
|
if (p <= nsqn) { |
|
2080
|
373
|
50
|
|
|
|
|
res = mont_mulmod(res, mont_powmod(mp,_powersin(p,n),m), m); |
|
2081
|
|
|
|
|
|
|
} else { |
|
2082
|
355724
|
100
|
|
|
|
|
while (p > nhi) { |
|
2083
|
2457
|
50
|
|
|
|
|
res = mont_mulmod(res, mont_powmod(s1,j,m), m); |
|
2084
|
2457
|
|
|
|
|
|
s1 = mont1; |
|
2085
|
2457
|
|
|
|
|
|
j--; |
|
2086
|
2457
|
|
|
|
|
|
nlo = n/(j+1)+1; |
|
2087
|
2457
|
|
|
|
|
|
nhi = n/j; |
|
2088
|
|
|
|
|
|
|
} |
|
2089
|
353267
|
50
|
|
|
|
|
if (p >= nlo) |
|
2090
|
353267
|
50
|
|
|
|
|
s1 = mont_mulmod(s1, mp, m); |
|
2091
|
|
|
|
|
|
|
} |
|
2092
|
353640
|
50
|
|
|
|
|
if (res == 0) break; |
|
2093
|
21043
|
|
|
|
|
|
END_DO_FOR_EACH_SIEVE_PRIME |
|
2094
|
|
|
|
|
|
|
} |
|
2095
|
2
|
|
|
|
|
|
end_segment_primes(ctx); |
|
2096
|
2
|
50
|
|
|
|
|
res = mont_mulmod(res, s1, m); |
|
2097
|
|
|
|
|
|
|
|
|
2098
|
|
|
|
|
|
|
} |
|
2099
|
|
|
|
|
|
|
|
|
2100
|
198
|
50
|
|
|
|
|
res = mont_recover(res, m); |
|
2101
|
198
|
|
|
|
|
|
return res; |
|
2102
|
|
|
|
|
|
|
} |
|
2103
|
|
|
|
|
|
|
#endif |
|
2104
|
|
|
|
|
|
|
|
|
2105
|
822
|
|
|
|
|
|
UV factorialmod(UV n, UV m) { /* n! mod m */ |
|
2106
|
822
|
|
|
|
|
|
UV d = n, res = 1; |
|
2107
|
|
|
|
|
|
|
uint32_t i; |
|
2108
|
|
|
|
|
|
|
bool m_prime; |
|
2109
|
|
|
|
|
|
|
|
|
2110
|
822
|
50
|
|
|
|
|
if (n >= m || m == 1) return 0; |
|
|
|
50
|
|
|
|
|
|
|
2111
|
822
|
100
|
|
|
|
|
if (n <= 1 || m == 2) return (n <= 1); |
|
|
|
50
|
|
|
|
|
|
|
2112
|
|
|
|
|
|
|
|
|
2113
|
744
|
100
|
|
|
|
|
if (n <= 10) { /* Keep things simple for small n */ |
|
2114
|
1594
|
100
|
|
|
|
|
for (i = 2; i <= n && res != 0; i++) |
|
|
|
100
|
|
|
|
|
|
|
2115
|
1288
|
|
|
|
|
|
res = (res * i) % m; |
|
2116
|
306
|
|
|
|
|
|
return res; |
|
2117
|
|
|
|
|
|
|
} |
|
2118
|
|
|
|
|
|
|
|
|
2119
|
438
|
|
|
|
|
|
m_prime = is_prime(m); |
|
2120
|
438
|
100
|
|
|
|
|
if (n > m/2 && m_prime) /* Check if we can go backwards */ |
|
|
|
100
|
|
|
|
|
|
|
2121
|
74
|
|
|
|
|
|
d = m-n-1; |
|
2122
|
438
|
100
|
|
|
|
|
if (d < 2) |
|
2123
|
14
|
100
|
|
|
|
|
return (d == 0) ? m-1 : 1; /* Wilson's Theorem: n = m-1 and n = m-2 */ |
|
2124
|
|
|
|
|
|
|
|
|
2125
|
424
|
100
|
|
|
|
|
if (d > 100 && !m_prime) { /* Check for composite m that leads to 0 */ |
|
|
|
100
|
|
|
|
|
|
|
2126
|
2
|
|
|
|
|
|
factored_t mf = factorint(m); |
|
2127
|
2
|
|
|
|
|
|
UV maxpk = 0; |
|
2128
|
8
|
100
|
|
|
|
|
for (i = 0; i < mf.nfactors; i++) { |
|
2129
|
6
|
|
|
|
|
|
UV t = mf.f[i] * mf.e[i]; /* Possibly too high if exp[j] > fac[j] */ |
|
2130
|
6
|
100
|
|
|
|
|
if (t > maxpk) |
|
2131
|
4
|
|
|
|
|
|
maxpk = t; |
|
2132
|
|
|
|
|
|
|
} |
|
2133
|
|
|
|
|
|
|
/* Maxpk is >= S(m), the Kempner number A002034 */ |
|
2134
|
2
|
100
|
|
|
|
|
if (n >= maxpk) |
|
2135
|
1
|
|
|
|
|
|
return 0; |
|
2136
|
|
|
|
|
|
|
} |
|
2137
|
|
|
|
|
|
|
|
|
2138
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
2139
|
423
|
100
|
|
|
|
|
if (m & 1) { |
|
2140
|
198
|
|
|
|
|
|
res = _facmod_mont(d, m); |
|
2141
|
|
|
|
|
|
|
} else |
|
2142
|
|
|
|
|
|
|
#endif |
|
2143
|
|
|
|
|
|
|
{ |
|
2144
|
225
|
|
|
|
|
|
res = _facmod(d, m); |
|
2145
|
|
|
|
|
|
|
} |
|
2146
|
|
|
|
|
|
|
|
|
2147
|
423
|
100
|
|
|
|
|
if (d != n && res != 0) { /* Handle backwards case */ |
|
|
|
50
|
|
|
|
|
|
|
2148
|
60
|
100
|
|
|
|
|
if (!(d&1)) res = submod(m,res,m); |
|
2149
|
60
|
|
|
|
|
|
res = modinverse(res,m); |
|
2150
|
|
|
|
|
|
|
} |
|
2151
|
|
|
|
|
|
|
|
|
2152
|
423
|
|
|
|
|
|
return res; |
|
2153
|
|
|
|
|
|
|
} |
|
2154
|
|
|
|
|
|
|
|
|
2155
|
|
|
|
|
|
|
|
|
2156
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2157
|
|
|
|
|
|
|
/* BINOMIAL(N,K) MOD M */ |
|
2158
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2159
|
|
|
|
|
|
|
|
|
2160
|
29013
|
|
|
|
|
|
static UV _factorial_valuation(UV n, UV p) { |
|
2161
|
29013
|
|
|
|
|
|
UV k = 0; |
|
2162
|
29013
|
50
|
|
|
|
|
while (n >= p) { |
|
2163
|
0
|
|
|
|
|
|
n /= p; |
|
2164
|
0
|
|
|
|
|
|
k += n; |
|
2165
|
|
|
|
|
|
|
} |
|
2166
|
29013
|
|
|
|
|
|
return k; |
|
2167
|
|
|
|
|
|
|
} |
|
2168
|
9671
|
|
|
|
|
|
static int _binoval(UV n, UV k, UV m) { |
|
2169
|
9671
|
|
|
|
|
|
return _factorial_valuation(n,m) - _factorial_valuation(k,m) - _factorial_valuation(n-k,m); |
|
2170
|
|
|
|
|
|
|
} |
|
2171
|
68818
|
|
|
|
|
|
static UV _factorialmod_without_prime(UV n, UV p, UV m) { |
|
2172
|
68818
|
|
|
|
|
|
UV i, pmod, r = 1; |
|
2173
|
68818
|
50
|
|
|
|
|
MPUassert(p >= 2 && m >= p && (m % p) == 0, "_factorialmod called with wrong args"); |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
2174
|
68818
|
100
|
|
|
|
|
if (n <= 1) return 1; |
|
2175
|
|
|
|
|
|
|
|
|
2176
|
26506
|
50
|
|
|
|
|
if (n >= m) { |
|
2177
|
|
|
|
|
|
|
/* Note with p=2 the behaviour is different */ |
|
2178
|
0
|
0
|
|
|
|
|
if ( ((n/m) & 1) && (p > 2 || m == 4) ) r = m-1; |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2179
|
0
|
|
|
|
|
|
n %= m; |
|
2180
|
|
|
|
|
|
|
} |
|
2181
|
|
|
|
|
|
|
|
|
2182
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
2183
|
26506
|
100
|
|
|
|
|
if (m & 1) { |
|
2184
|
13299
|
|
|
|
|
|
const uint64_t npi = mont_inverse(m), mont1 = mont_get1(m); |
|
2185
|
13299
|
|
|
|
|
|
uint64_t mi = mont1; |
|
2186
|
13299
|
|
|
|
|
|
r = mont_geta(r, m); |
|
2187
|
374270
|
100
|
|
|
|
|
for (i = pmod = 2; i <= n; i++) { |
|
2188
|
360971
|
|
|
|
|
|
mi = addmod(mi, mont1, m); |
|
2189
|
360971
|
100
|
|
|
|
|
if (pmod++ == p) pmod = 1; |
|
2190
|
351317
|
50
|
|
|
|
|
else r = mont_mulmod(r, mi, m); |
|
2191
|
|
|
|
|
|
|
} |
|
2192
|
13299
|
50
|
|
|
|
|
r = mont_recover(r, m); |
|
2193
|
|
|
|
|
|
|
} else |
|
2194
|
|
|
|
|
|
|
#endif |
|
2195
|
|
|
|
|
|
|
{ |
|
2196
|
46712
|
100
|
|
|
|
|
for (i = pmod = 2; i <= n; i++) { |
|
2197
|
33505
|
100
|
|
|
|
|
if (pmod++ == p) pmod = 1; |
|
2198
|
12951
|
|
|
|
|
|
else r = mulmod(r, i, m); |
|
2199
|
|
|
|
|
|
|
} |
|
2200
|
|
|
|
|
|
|
} |
|
2201
|
26506
|
|
|
|
|
|
return r; |
|
2202
|
|
|
|
|
|
|
} |
|
2203
|
2995
|
|
|
|
|
|
static UV _factorialmod_without_prime_powers(UV n, UV p, UV m) { |
|
2204
|
2995
|
|
|
|
|
|
UV ip, r = 1; |
|
2205
|
|
|
|
|
|
|
|
|
2206
|
5990
|
100
|
|
|
|
|
for (ip = n; ip > 1; ip /= p) |
|
2207
|
2995
|
|
|
|
|
|
r = mulmod(r, _factorialmod_without_prime(ip, p, m), m); |
|
2208
|
|
|
|
|
|
|
|
|
2209
|
2995
|
|
|
|
|
|
return r; |
|
2210
|
|
|
|
|
|
|
} |
|
2211
|
39749
|
|
|
|
|
|
static UV _binomial_mod_prime_power(UV n, UV k, UV p, UV e) { |
|
2212
|
|
|
|
|
|
|
UV r, b, m, i, num, den, ip, ires; |
|
2213
|
|
|
|
|
|
|
|
|
2214
|
39749
|
100
|
|
|
|
|
if (k > n) return 0; |
|
2215
|
30104
|
100
|
|
|
|
|
if (k == 0 || k == n) return 1; |
|
|
|
100
|
|
|
|
|
|
|
2216
|
9671
|
100
|
|
|
|
|
if (k > n/2) k = n-k; |
|
2217
|
|
|
|
|
|
|
|
|
2218
|
9671
|
|
|
|
|
|
b = _binoval(n,k,p); |
|
2219
|
9671
|
50
|
|
|
|
|
if (e <= b) return 0; |
|
2220
|
9671
|
|
|
|
|
|
m = ipow(p,e); |
|
2221
|
|
|
|
|
|
|
|
|
2222
|
9671
|
100
|
|
|
|
|
if (k == 1) return n % m; |
|
2223
|
|
|
|
|
|
|
|
|
2224
|
|
|
|
|
|
|
/* Both methods work fine -- choose based on performance. */ |
|
2225
|
2995
|
|
|
|
|
|
den = _factorialmod_without_prime_powers(k, p, m); |
|
2226
|
2995
|
50
|
|
|
|
|
if (k >= m) { |
|
2227
|
0
|
|
|
|
|
|
num = _factorialmod_without_prime_powers(n, p, m); |
|
2228
|
0
|
|
|
|
|
|
ip = _factorialmod_without_prime_powers(n-k, p, m); |
|
2229
|
0
|
|
|
|
|
|
den = mulmod(den, ip, m); |
|
2230
|
|
|
|
|
|
|
} else { |
|
2231
|
|
|
|
|
|
|
#if USE_MONTMATH |
|
2232
|
2995
|
50
|
|
|
|
|
if (m & 1) { |
|
2233
|
2995
|
|
|
|
|
|
const uint64_t npi = mont_inverse(m), mont1 = mont_get1(m); |
|
2234
|
2995
|
|
|
|
|
|
num = mont1; |
|
2235
|
80764
|
100
|
|
|
|
|
for (i = n-k+1, ires = (i-1)%p; i <= n; i++) { |
|
2236
|
77769
|
|
|
|
|
|
ip = i; |
|
2237
|
77769
|
50
|
|
|
|
|
if (++ires == p) { ires = 0; do { ip /= p; } while ((ip % p) == 0); } |
|
|
|
0
|
|
|
|
|
|
|
2238
|
77769
|
50
|
|
|
|
|
num = mont_mulmod(num, mont_geta(ip, m), m); |
|
2239
|
|
|
|
|
|
|
} |
|
2240
|
2995
|
50
|
|
|
|
|
num = mont_recover(num, m); |
|
2241
|
|
|
|
|
|
|
} else |
|
2242
|
|
|
|
|
|
|
#endif |
|
2243
|
|
|
|
|
|
|
{ |
|
2244
|
0
|
|
|
|
|
|
num = 1; |
|
2245
|
0
|
0
|
|
|
|
|
for (i = n-k+1, ires = (i-1) % p; i <= n; i++) { |
|
2246
|
0
|
|
|
|
|
|
ip = i; |
|
2247
|
0
|
0
|
|
|
|
|
if (++ires == p) { ires = 0; do { ip /= p; } while ((ip % p) == 0); } |
|
|
|
0
|
|
|
|
|
|
|
2248
|
0
|
|
|
|
|
|
num = mulmod(num, ip, m); |
|
2249
|
|
|
|
|
|
|
} |
|
2250
|
|
|
|
|
|
|
} |
|
2251
|
|
|
|
|
|
|
} |
|
2252
|
|
|
|
|
|
|
|
|
2253
|
2995
|
|
|
|
|
|
r = divmod(num, den, m); |
|
2254
|
2995
|
50
|
|
|
|
|
if (b > 0) r = mulmod(r, ipow(p,b), m); |
|
2255
|
2995
|
|
|
|
|
|
return r; |
|
2256
|
|
|
|
|
|
|
} |
|
2257
|
|
|
|
|
|
|
|
|
2258
|
20303
|
|
|
|
|
|
static UV _binomial_lucas_mod_prime(UV n, UV k, UV p) { |
|
2259
|
|
|
|
|
|
|
UV res, t, vn[BITS_PER_WORD], vk[BITS_PER_WORD]; |
|
2260
|
|
|
|
|
|
|
int i, ln, lk; |
|
2261
|
|
|
|
|
|
|
|
|
2262
|
20303
|
50
|
|
|
|
|
if (p < 2) return 0; |
|
2263
|
20303
|
100
|
|
|
|
|
if (p == 2) return !(~n & k); |
|
2264
|
|
|
|
|
|
|
|
|
2265
|
55371
|
100
|
|
|
|
|
for (t = n, ln = 0; t > 0; t /= p) |
|
2266
|
39749
|
|
|
|
|
|
vn[ln++] = t % p; |
|
2267
|
46010
|
100
|
|
|
|
|
for (t = k, lk = 0; t > 0; t /= p) |
|
2268
|
30388
|
|
|
|
|
|
vk[lk++] = t % p; |
|
2269
|
|
|
|
|
|
|
|
|
2270
|
15622
|
|
|
|
|
|
res = 1; |
|
2271
|
55371
|
100
|
|
|
|
|
for (i = ln-1; i >= 0; i--) { |
|
2272
|
39749
|
|
|
|
|
|
UV ni = vn[i]; |
|
2273
|
39749
|
100
|
|
|
|
|
UV ki = (i < lk) ? vk[i] : 0; |
|
2274
|
39749
|
|
|
|
|
|
res = mulmod(res, _binomial_mod_prime_power(ni, ki, p, 1), p); |
|
2275
|
|
|
|
|
|
|
} |
|
2276
|
15622
|
|
|
|
|
|
return res; |
|
2277
|
|
|
|
|
|
|
} |
|
2278
|
|
|
|
|
|
|
|
|
2279
|
|
|
|
|
|
|
/* Based on Granville's paper on the generalization of Lucas's theorem to |
|
2280
|
|
|
|
|
|
|
* prime powers: https://www.dms.umontreal.ca/~andrew/Binomial/genlucas.html |
|
2281
|
|
|
|
|
|
|
* and Max Alekseyev's binomod.gp program. */ |
|
2282
|
7812
|
|
|
|
|
|
static UV _binomial_lucas_mod_prime_power(UV n, UV k, UV p, UV q) { |
|
2283
|
|
|
|
|
|
|
UV N[BITS_PER_WORD], K[BITS_PER_WORD], R[BITS_PER_WORD], e[BITS_PER_WORD]; |
|
2284
|
|
|
|
|
|
|
UV i, d, m, n1, k1, r1, m1, res; |
|
2285
|
|
|
|
|
|
|
|
|
2286
|
7812
|
50
|
|
|
|
|
MPUassert(q < BITS_PER_WORD, "bad exponent in binomialmod generalized lucas"); |
|
2287
|
7812
|
|
|
|
|
|
m = ipow(p, q); |
|
2288
|
|
|
|
|
|
|
|
|
2289
|
|
|
|
|
|
|
/* Construct the digits for N, K, and N-K (R). */ |
|
2290
|
7812
|
|
|
|
|
|
n1 = n; k1 = k; r1 = n-k; |
|
2291
|
42811
|
100
|
|
|
|
|
for (d = 0; n1 > 0; d++) { |
|
2292
|
34999
|
|
|
|
|
|
N[d] = n1 % p; n1 /= p; |
|
2293
|
34999
|
|
|
|
|
|
K[d] = k1 % p; k1 /= p; |
|
2294
|
34999
|
|
|
|
|
|
R[d] = r1 % p; r1 /= p; |
|
2295
|
|
|
|
|
|
|
} |
|
2296
|
|
|
|
|
|
|
/* Compute the number of carries. */ |
|
2297
|
42811
|
100
|
|
|
|
|
for (i = 0; i < d; i++) |
|
2298
|
34999
|
100
|
|
|
|
|
e[i] = (N[i] < (K[i] + ((i > 0) ? e[i-1] : 0))); |
|
2299
|
|
|
|
|
|
|
/* Turn the carries into a cumulative count. */ |
|
2300
|
34999
|
100
|
|
|
|
|
for (i = d-1; i >= 1; i--) |
|
2301
|
27187
|
|
|
|
|
|
e[i-1] += e[i]; |
|
2302
|
|
|
|
|
|
|
|
|
2303
|
7812
|
100
|
|
|
|
|
if (e[0] >= q) return 0; |
|
2304
|
5205
|
|
|
|
|
|
q -= e[0]; |
|
2305
|
5205
|
|
|
|
|
|
m1 = ipow(p, q); |
|
2306
|
|
|
|
|
|
|
|
|
2307
|
|
|
|
|
|
|
/* Now make the digits for the reduced N, K, N-K */ |
|
2308
|
5205
|
|
|
|
|
|
n1 = n; k1 = k; r1 = n-k; |
|
2309
|
27146
|
100
|
|
|
|
|
for (d = 0; n1 > 0; d++) { |
|
2310
|
21941
|
|
|
|
|
|
N[d] = n1 % m1; n1 /= p; |
|
2311
|
21941
|
|
|
|
|
|
K[d] = k1 % m1; k1 /= p; |
|
2312
|
21941
|
|
|
|
|
|
R[d] = r1 % m1; r1 /= p; |
|
2313
|
|
|
|
|
|
|
} |
|
2314
|
|
|
|
|
|
|
|
|
2315
|
|
|
|
|
|
|
/* Theorem 1 from Granville indicates the +/- 1. */ |
|
2316
|
5205
|
100
|
|
|
|
|
res = ((p > 2 || q < 3) && q < d && e[q-1] % 2) ? m-1 : 1; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
2317
|
5205
|
|
|
|
|
|
res = mulmod(res, powmod(p, e[0], m), m); |
|
2318
|
|
|
|
|
|
|
|
|
2319
|
|
|
|
|
|
|
/* Compute the individual binomials (again, theorem 1) */ |
|
2320
|
27146
|
100
|
|
|
|
|
for (i = 0; i < d; i++) { |
|
2321
|
21941
|
|
|
|
|
|
UV ni = _factorialmod_without_prime(N[i], p, m); |
|
2322
|
21941
|
|
|
|
|
|
UV ki = _factorialmod_without_prime(K[i], p, m); |
|
2323
|
21941
|
|
|
|
|
|
UV ri = _factorialmod_without_prime(R[i], p, m); |
|
2324
|
21941
|
|
|
|
|
|
UV r = divmod(ni, mulmod(ki, ri, m), m); |
|
2325
|
21941
|
|
|
|
|
|
res = mulmod(res, r, m); |
|
2326
|
|
|
|
|
|
|
} |
|
2327
|
5205
|
|
|
|
|
|
return res; |
|
2328
|
|
|
|
|
|
|
} |
|
2329
|
|
|
|
|
|
|
|
|
2330
|
21344
|
|
|
|
|
|
bool binomialmod(UV *res, UV n, UV k, UV m) { |
|
2331
|
|
|
|
|
|
|
|
|
2332
|
21344
|
50
|
|
|
|
|
if (m <= 1) { *res = 0; return 1; } |
|
2333
|
21344
|
100
|
|
|
|
|
if (k == 0 || k >= n) { *res = (k == 0 || k == n); return 1; } |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
2334
|
|
|
|
|
|
|
|
|
2335
|
20302
|
100
|
|
|
|
|
if (m == 2) { *res = !(~n & k); return 1; } |
|
2336
|
|
|
|
|
|
|
|
|
2337
|
|
|
|
|
|
|
#if 0 |
|
2338
|
|
|
|
|
|
|
if ( (*res = binomial(n,k)) ) |
|
2339
|
|
|
|
|
|
|
{ *res %= m; return 1; } |
|
2340
|
|
|
|
|
|
|
#endif |
|
2341
|
|
|
|
|
|
|
|
|
2342
|
19522
|
100
|
|
|
|
|
if (is_prime(m)) { |
|
2343
|
6247
|
|
|
|
|
|
*res = _binomial_lucas_mod_prime(n, k, m); |
|
2344
|
6247
|
|
|
|
|
|
return 1; |
|
2345
|
|
|
|
|
|
|
} |
|
2346
|
|
|
|
|
|
|
{ |
|
2347
|
|
|
|
|
|
|
UV bin[MPU_MAX_DFACTORS], mod[MPU_MAX_DFACTORS]; |
|
2348
|
|
|
|
|
|
|
uint32_t i; |
|
2349
|
13275
|
|
|
|
|
|
factored_t mf = factorint(m); |
|
2350
|
|
|
|
|
|
|
|
|
2351
|
35143
|
100
|
|
|
|
|
for (i = 0; i < mf.nfactors; i++) { |
|
2352
|
21868
|
100
|
|
|
|
|
if (mf.e[i] == 1) { |
|
2353
|
14056
|
|
|
|
|
|
bin[i] = _binomial_lucas_mod_prime(n, k, mf.f[i]); |
|
2354
|
14056
|
|
|
|
|
|
mod[i] = mf.f[i]; |
|
2355
|
|
|
|
|
|
|
} else { |
|
2356
|
|
|
|
|
|
|
/* bin[i] = _binomial_mod_prime_power(n, k, mf.f[i], mf.e[i]); */ |
|
2357
|
|
|
|
|
|
|
/* Use generalized Lucas */ |
|
2358
|
7812
|
|
|
|
|
|
bin[i] = _binomial_lucas_mod_prime_power(n, k, mf.f[i], mf.e[i]); |
|
2359
|
7812
|
|
|
|
|
|
mod[i] = ipow(mf.f[i], mf.e[i]); |
|
2360
|
|
|
|
|
|
|
} |
|
2361
|
|
|
|
|
|
|
} |
|
2362
|
|
|
|
|
|
|
/* chinese with p^e as modulos, so should never get -1 back */ |
|
2363
|
13275
|
|
|
|
|
|
return chinese(res, 0, bin, mod, mf.nfactors) == 1; |
|
2364
|
|
|
|
|
|
|
} |
|
2365
|
|
|
|
|
|
|
} |
|
2366
|
|
|
|
|
|
|
|
|
2367
|
|
|
|
|
|
|
/* Pisano period. */ |
|
2368
|
|
|
|
|
|
|
/* Thanks to Trizen & Charles R Greathouse IV for ideas and working examples. */ |
|
2369
|
|
|
|
|
|
|
/* Algorithm from Charles R Greathouse IV, https://oeis.org/A001175 */ |
|
2370
|
342
|
|
|
|
|
|
static UV _pisano_prime_power(UV p, UV e) |
|
2371
|
|
|
|
|
|
|
{ |
|
2372
|
|
|
|
|
|
|
UV k; |
|
2373
|
342
|
50
|
|
|
|
|
if (e == 0) return 1; |
|
2374
|
342
|
100
|
|
|
|
|
if (p == 2) return 3UL << (e-1); |
|
2375
|
249
|
100
|
|
|
|
|
if (p == 3) k = 8; |
|
2376
|
188
|
100
|
|
|
|
|
else if (p == 5) k = 20; |
|
2377
|
149
|
100
|
|
|
|
|
else if (p == 7) k = 16; |
|
2378
|
123
|
100
|
|
|
|
|
else if (p < 300) { /* Simple search */ |
|
2379
|
120
|
|
|
|
|
|
UV a = 1,b = 1, t; |
|
2380
|
120
|
|
|
|
|
|
k = 1; |
|
2381
|
7612
|
100
|
|
|
|
|
while (!(a == 0 && b == 1)) { |
|
|
|
100
|
|
|
|
|
|
|
2382
|
7492
|
|
|
|
|
|
k++; |
|
2383
|
7492
|
|
|
|
|
|
t = b; b = addmod(a,b,p); a = t; |
|
2384
|
|
|
|
|
|
|
} |
|
2385
|
|
|
|
|
|
|
} else { /* Look through divisors of p-(5|p) */ |
|
2386
|
|
|
|
|
|
|
factored_t kf; |
|
2387
|
|
|
|
|
|
|
uint32_t i, j; |
|
2388
|
|
|
|
|
|
|
|
|
2389
|
3
|
|
|
|
|
|
k = p - kronecker_uu(5,p); |
|
2390
|
3
|
|
|
|
|
|
kf = factorint(k); |
|
2391
|
13
|
100
|
|
|
|
|
for (i = 0; i < kf.nfactors; i++) { |
|
2392
|
16
|
100
|
|
|
|
|
for (j = 0; j < kf.e[i]; j++) { |
|
2393
|
11
|
100
|
|
|
|
|
if (lucasumod(1, p-1, k/kf.f[i], p) != 0) break; |
|
2394
|
6
|
|
|
|
|
|
k /= kf.f[i]; |
|
2395
|
|
|
|
|
|
|
} |
|
2396
|
|
|
|
|
|
|
} |
|
2397
|
|
|
|
|
|
|
} |
|
2398
|
249
|
100
|
|
|
|
|
return (e == 1) ? k : k * ipow(p, e-1); |
|
2399
|
|
|
|
|
|
|
} |
|
2400
|
187
|
|
|
|
|
|
UV pisano_period(UV n) |
|
2401
|
|
|
|
|
|
|
{ |
|
2402
|
|
|
|
|
|
|
factored_t nf; |
|
2403
|
|
|
|
|
|
|
UV r, lim, k; |
|
2404
|
|
|
|
|
|
|
uint32_t i; |
|
2405
|
|
|
|
|
|
|
|
|
2406
|
187
|
100
|
|
|
|
|
if (n <= 1) return (n == 1); |
|
2407
|
|
|
|
|
|
|
|
|
2408
|
185
|
|
|
|
|
|
nf = factorint(n); |
|
2409
|
526
|
100
|
|
|
|
|
for (i = 0, k = 1; i < nf.nfactors; i++) { |
|
2410
|
342
|
|
|
|
|
|
k = lcmsafe(k, _pisano_prime_power(nf.f[i], nf.e[i])); |
|
2411
|
342
|
100
|
|
|
|
|
if (k == 0) return 0; |
|
2412
|
|
|
|
|
|
|
} |
|
2413
|
|
|
|
|
|
|
|
|
2414
|
|
|
|
|
|
|
/* Do this carefully to avoid overflow */ |
|
2415
|
184
|
|
|
|
|
|
r = 0; |
|
2416
|
184
|
50
|
|
|
|
|
lim = (UV_MAX/6 < n) ? UV_MAX : 6*n; |
|
2417
|
|
|
|
|
|
|
do { |
|
2418
|
188
|
|
|
|
|
|
r += k; |
|
2419
|
188
|
100
|
|
|
|
|
if (lucasumod(1, n-1, r-1, n) == 1) |
|
2420
|
184
|
|
|
|
|
|
return r; |
|
2421
|
4
|
50
|
|
|
|
|
} while (r <= (lim-k)); |
|
2422
|
|
|
|
|
|
|
|
|
2423
|
0
|
|
|
|
|
|
return 0; |
|
2424
|
|
|
|
|
|
|
} |
|
2425
|
|
|
|
|
|
|
|
|
2426
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2427
|
|
|
|
|
|
|
/* HAPPY */ |
|
2428
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2429
|
|
|
|
|
|
|
|
|
2430
|
49246
|
|
|
|
|
|
static UV sum_of_digits(UV n, uint32_t base, uint32_t k) { |
|
2431
|
49246
|
|
|
|
|
|
UV t, r, sum = 0; |
|
2432
|
180846
|
100
|
|
|
|
|
while (n) { |
|
2433
|
131600
|
|
|
|
|
|
t = n / base; |
|
2434
|
131600
|
|
|
|
|
|
r = n - base * t; |
|
2435
|
131600
|
|
|
|
|
|
switch (k) { |
|
2436
|
0
|
|
|
|
|
|
case 0: sum += 1; break; |
|
2437
|
0
|
|
|
|
|
|
case 1: sum += r; break; |
|
2438
|
42733
|
|
|
|
|
|
case 2: sum += r*r; break; |
|
2439
|
88867
|
|
|
|
|
|
default: sum += ipow(r,k); break; |
|
2440
|
|
|
|
|
|
|
} |
|
2441
|
131600
|
|
|
|
|
|
n = t; |
|
2442
|
|
|
|
|
|
|
} |
|
2443
|
49246
|
|
|
|
|
|
return sum; |
|
2444
|
|
|
|
|
|
|
} |
|
2445
|
924
|
|
|
|
|
|
static UV sum_of_squared_digits(UV n) { |
|
2446
|
924
|
|
|
|
|
|
UV t, r, sum = 0; |
|
2447
|
3803
|
100
|
|
|
|
|
while (n) { |
|
2448
|
2879
|
|
|
|
|
|
t = n / 10; |
|
2449
|
2879
|
|
|
|
|
|
r = n - 10 * t; |
|
2450
|
2879
|
|
|
|
|
|
sum += r*r; |
|
2451
|
2879
|
|
|
|
|
|
n = t; |
|
2452
|
|
|
|
|
|
|
} |
|
2453
|
924
|
|
|
|
|
|
return sum; |
|
2454
|
|
|
|
|
|
|
} |
|
2455
|
|
|
|
|
|
|
|
|
2456
|
4974
|
|
|
|
|
|
int happy_height(UV n, uint32_t base, uint32_t exponent) { |
|
2457
|
|
|
|
|
|
|
int h; |
|
2458
|
|
|
|
|
|
|
|
|
2459
|
4974
|
100
|
|
|
|
|
if (base == 10 && exponent == 2) { |
|
|
|
100
|
|
|
|
|
|
|
2460
|
|
|
|
|
|
|
static const char sh[101] = {0,1,0,0,0,0,0,6,0,0,2,0,0,3,0,0,0,0,0,5,0,0,0,4,0,0,0,0,4,0,0,3,4,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,6,0,0,0,0,0,0,0,0,4,0,0,4,0,0,0,3,0,0,0,0,5,0,0,5,0,0,4,0,0,2}; |
|
2461
|
1780
|
100
|
|
|
|
|
for (h = 0; n > 100; h++) |
|
2462
|
924
|
|
|
|
|
|
n = sum_of_squared_digits(n); |
|
2463
|
856
|
100
|
|
|
|
|
return (sh[n] == 0) ? 0 : h+sh[n]; |
|
2464
|
|
|
|
|
|
|
} else { |
|
2465
|
4118
|
|
|
|
|
|
UV ncheck = 0; |
|
2466
|
53364
|
100
|
|
|
|
|
for (h = 1; n > 1 && n != ncheck; h++) { |
|
|
|
100
|
|
|
|
|
|
|
2467
|
49246
|
100
|
|
|
|
|
if ((h & (h-1)) == 0) ncheck = n; /* Brent cycle finding */ |
|
2468
|
49246
|
|
|
|
|
|
n = sum_of_digits(n, base, exponent); |
|
2469
|
|
|
|
|
|
|
} |
|
2470
|
|
|
|
|
|
|
} |
|
2471
|
4118
|
100
|
|
|
|
|
return (n == 1) ? h : 0; |
|
2472
|
|
|
|
|
|
|
} |
|
2473
|
|
|
|
|
|
|
|
|
2474
|
|
|
|
|
|
|
|
|
2475
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2476
|
|
|
|
|
|
|
/* CRT */ |
|
2477
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2478
|
|
|
|
|
|
|
|
|
2479
|
|
|
|
|
|
|
/* works only for co-prime inputs and also slower than the algorithm below, |
|
2480
|
|
|
|
|
|
|
* but handles the case where IV_MAX < lcm <= UV_MAX. |
|
2481
|
|
|
|
|
|
|
* status = 1 means good result, 0 means try another method. |
|
2482
|
|
|
|
|
|
|
*/ |
|
2483
|
14
|
|
|
|
|
|
static bool _simple_chinese(UV *r, UV *mod, const UV* a, const UV* n, UV num) { |
|
2484
|
14
|
|
|
|
|
|
UV i, lcm = 1, res = 0; |
|
2485
|
14
|
50
|
|
|
|
|
if (num == 0) { *r = 0; if (mod) *mod = 0; return 1; } /* Dubious return */ |
|
|
|
0
|
|
|
|
|
|
|
2486
|
|
|
|
|
|
|
|
|
2487
|
35
|
100
|
|
|
|
|
for (i = 0; i < num; i++) { |
|
2488
|
33
|
|
|
|
|
|
UV ni = n[i]; |
|
2489
|
33
|
|
|
|
|
|
UV gcd = gcd_ui(lcm, ni); |
|
2490
|
33
|
100
|
|
|
|
|
if (gcd != 1) return 0; /* not coprime */ |
|
2491
|
27
|
|
|
|
|
|
ni /= gcd; |
|
2492
|
27
|
100
|
|
|
|
|
if (ni > (UV_MAX/lcm)) return 0; /* lcm overflow */ |
|
2493
|
21
|
|
|
|
|
|
lcm *= ni; |
|
2494
|
|
|
|
|
|
|
} |
|
2495
|
10
|
100
|
|
|
|
|
for (i = 0; i < num; i++) { |
|
2496
|
|
|
|
|
|
|
UV p, inverse, term; |
|
2497
|
8
|
|
|
|
|
|
p = lcm / n[i]; |
|
2498
|
8
|
|
|
|
|
|
inverse = modinverse(p, n[i]); |
|
2499
|
8
|
50
|
|
|
|
|
if (inverse == 0) return 0; /* n's coprime so should never happen */ |
|
2500
|
8
|
|
|
|
|
|
term = mulmod(p, mulmod(a[i], inverse, lcm), lcm); |
|
2501
|
8
|
|
|
|
|
|
res = addmod(res, term, lcm); |
|
2502
|
|
|
|
|
|
|
} |
|
2503
|
2
|
|
|
|
|
|
*r = res; |
|
2504
|
2
|
50
|
|
|
|
|
if (mod) *mod = lcm; |
|
2505
|
2
|
|
|
|
|
|
return 1; |
|
2506
|
|
|
|
|
|
|
} |
|
2507
|
|
|
|
|
|
|
|
|
2508
|
|
|
|
|
|
|
/* status: 1 ok, -1 no inverse, 0 overflow */ |
|
2509
|
13351
|
|
|
|
|
|
int chinese(UV *r, UV *mod, UV* a, UV* n, UV num) { |
|
2510
|
|
|
|
|
|
|
static unsigned short sgaps[] = {7983,3548,1577,701,301,132,57,23,10,4,1,0}; |
|
2511
|
|
|
|
|
|
|
UV gcd, i, j, lcm, sum, gi, gap; |
|
2512
|
13351
|
100
|
|
|
|
|
if (num == 0) { *r = 0; if (mod) *mod = 0; return 1; } /* Dubious return */ |
|
|
|
50
|
|
|
|
|
|
|
2513
|
|
|
|
|
|
|
|
|
2514
|
|
|
|
|
|
|
/* Sort modulii, largest first */ |
|
2515
|
160188
|
100
|
|
|
|
|
for (gi = 0, gap = sgaps[gi]; gap >= 1; gap = sgaps[++gi]) { |
|
2516
|
155526
|
100
|
|
|
|
|
for (i = gap; i < num; i++) { |
|
2517
|
8687
|
|
|
|
|
|
UV tn = n[i], ta = a[i]; |
|
2518
|
15823
|
100
|
|
|
|
|
for (j = i; j >= gap && n[j-gap] < tn; j -= gap) |
|
|
|
100
|
|
|
|
|
|
|
2519
|
7136
|
|
|
|
|
|
{ n[j] = n[j-gap]; a[j] = a[j-gap]; } |
|
2520
|
8687
|
|
|
|
|
|
n[j] = tn; a[j] = ta; |
|
2521
|
|
|
|
|
|
|
} |
|
2522
|
|
|
|
|
|
|
} |
|
2523
|
|
|
|
|
|
|
|
|
2524
|
13349
|
50
|
|
|
|
|
if (n[num-1] == 0) return -1; /* mod 0 */ |
|
2525
|
13349
|
100
|
|
|
|
|
if (n[0] > IV_MAX) return _simple_chinese(r,mod,a,n,num); |
|
2526
|
13347
|
|
|
|
|
|
lcm = n[0]; sum = a[0] % n[0]; |
|
2527
|
22011
|
100
|
|
|
|
|
for (i = 1; i < num; i++) { |
|
2528
|
|
|
|
|
|
|
IV u, v, t, s; |
|
2529
|
|
|
|
|
|
|
UV vs, ut; |
|
2530
|
8680
|
|
|
|
|
|
gcd = gcdext(lcm, n[i], &u, &v, &s, &t); |
|
2531
|
8692
|
100
|
|
|
|
|
if (gcd != 1 && ((sum % gcd) != (a[i] % gcd))) return -1; |
|
|
|
100
|
|
|
|
|
|
|
2532
|
8676
|
100
|
|
|
|
|
if (s < 0) s = -s; |
|
2533
|
8676
|
100
|
|
|
|
|
if (t < 0) t = -t; |
|
2534
|
8676
|
100
|
|
|
|
|
if (s > (IV)(IV_MAX/lcm)) return _simple_chinese(r,mod,a,n,num); |
|
2535
|
8664
|
|
|
|
|
|
lcm *= s; |
|
2536
|
8664
|
100
|
|
|
|
|
if (u < 0) u += lcm; |
|
2537
|
8664
|
100
|
|
|
|
|
if (v < 0) v += lcm; |
|
2538
|
8664
|
|
|
|
|
|
vs = mulmod((UV)v, (UV)s, lcm); |
|
2539
|
8664
|
|
|
|
|
|
ut = mulmod((UV)u, (UV)t, lcm); |
|
2540
|
8664
|
|
|
|
|
|
sum = addmod( mulmod(vs, sum, lcm), mulmod(ut, a[i], lcm), lcm ); |
|
2541
|
|
|
|
|
|
|
} |
|
2542
|
13331
|
|
|
|
|
|
*r = sum; |
|
2543
|
13331
|
100
|
|
|
|
|
if (mod) *mod = lcm; |
|
2544
|
13331
|
|
|
|
|
|
return 1; |
|
2545
|
|
|
|
|
|
|
} |
|
2546
|
|
|
|
|
|
|
|
|
2547
|
487
|
|
|
|
|
|
bool prep_pow_inv(UV *a, UV *k, int kstatus, UV n) { |
|
2548
|
487
|
50
|
|
|
|
|
if (n == 0) return 0; |
|
2549
|
487
|
100
|
|
|
|
|
if (kstatus < 0) { |
|
2550
|
40
|
100
|
|
|
|
|
if (*a != 0) *a = modinverse(*a, n); |
|
2551
|
40
|
100
|
|
|
|
|
if (*a == 0) return 0; |
|
2552
|
21
|
|
|
|
|
|
*k = -(IV)*k; |
|
2553
|
|
|
|
|
|
|
} |
|
2554
|
468
|
|
|
|
|
|
return 1; |
|
2555
|
|
|
|
|
|
|
} |
|
2556
|
|
|
|
|
|
|
|
|
2557
|
|
|
|
|
|
|
|
|
2558
|
|
|
|
|
|
|
|
|
2559
|
|
|
|
|
|
|
#if HAVE_UINT64 |
|
2560
|
|
|
|
|
|
|
#define U64T uint64_t |
|
2561
|
|
|
|
|
|
|
#else |
|
2562
|
|
|
|
|
|
|
#define U64T UV |
|
2563
|
|
|
|
|
|
|
#endif |
|
2564
|
|
|
|
|
|
|
|
|
2565
|
|
|
|
|
|
|
/* Spigot from Arndt, Haenel, Winter, and Flammenkamp. */ |
|
2566
|
|
|
|
|
|
|
/* Modified for larger digits and rounding by Dana Jacobsen */ |
|
2567
|
987
|
|
|
|
|
|
char* pidigits(uint32_t digits) |
|
2568
|
|
|
|
|
|
|
{ |
|
2569
|
|
|
|
|
|
|
char* out; |
|
2570
|
|
|
|
|
|
|
uint32_t *a, b, c, d, e, g, i, d4, d3, d2, d1; |
|
2571
|
987
|
|
|
|
|
|
uint32_t const f = 10000; |
|
2572
|
|
|
|
|
|
|
U64T d64; /* 64-bit intermediate for 2*2*10000*b > 2^32 (~30k digits) */ |
|
2573
|
|
|
|
|
|
|
|
|
2574
|
987
|
50
|
|
|
|
|
if (digits == 0) return 0; |
|
2575
|
987
|
50
|
|
|
|
|
if (digits >= 1 && digits <= DBL_DIG && digits <= 18) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
2576
|
15
|
|
|
|
|
|
Newz(0, out, 20, char); |
|
2577
|
15
|
|
|
|
|
|
(void)snprintf(out, 20, "%.*lf", (digits-1), 3.141592653589793238); |
|
2578
|
15
|
|
|
|
|
|
return out; |
|
2579
|
|
|
|
|
|
|
} |
|
2580
|
972
|
|
|
|
|
|
digits++; /* For rounding */ |
|
2581
|
972
|
|
|
|
|
|
c = 14*(digits/4 + 2); |
|
2582
|
|
|
|
|
|
|
/* 1 for decimal point, 3 for possible extra in loop. */ |
|
2583
|
972
|
|
|
|
|
|
New(0, out, digits+1+3, char); |
|
2584
|
972
|
|
|
|
|
|
*out++ = '3'; /* We'll turn "31415..." below into ".1415..." */ |
|
2585
|
972
|
|
|
|
|
|
New(0, a, c, uint32_t); |
|
2586
|
1776998
|
100
|
|
|
|
|
for (b = 0; b < c; b++) a[b] = 2000; |
|
2587
|
|
|
|
|
|
|
|
|
2588
|
972
|
|
|
|
|
|
d = i = 0; |
|
2589
|
126616
|
100
|
|
|
|
|
while (i < digits) { |
|
2590
|
125644
|
|
|
|
|
|
b = c -= 14; |
|
2591
|
125644
|
|
|
|
|
|
d = e = d % f; |
|
2592
|
125644
|
50
|
|
|
|
|
if (b > 107001) { /* Use 64-bit intermediate while necessary. */ |
|
2593
|
0
|
0
|
|
|
|
|
for (d64 = d; --b > 107000; ) { |
|
2594
|
0
|
|
|
|
|
|
g = (b << 1) - 1; |
|
2595
|
0
|
|
|
|
|
|
d64 = d64 * b + f * (U64T)a[b]; |
|
2596
|
0
|
|
|
|
|
|
a[b] = d64 % g; |
|
2597
|
0
|
|
|
|
|
|
d64 /= g; |
|
2598
|
|
|
|
|
|
|
} |
|
2599
|
0
|
|
|
|
|
|
d = d64; |
|
2600
|
0
|
|
|
|
|
|
b++; |
|
2601
|
|
|
|
|
|
|
} |
|
2602
|
148467144
|
100
|
|
|
|
|
while (--b > 0) { |
|
2603
|
148341500
|
|
|
|
|
|
g = (b << 1) - 1; |
|
2604
|
148341500
|
|
|
|
|
|
d = d * b + f * a[b]; |
|
2605
|
148341500
|
|
|
|
|
|
a[b] = d % g; |
|
2606
|
148341500
|
|
|
|
|
|
d /= g; |
|
2607
|
|
|
|
|
|
|
} |
|
2608
|
|
|
|
|
|
|
/* sprintf(out+i, "%04d", e+d/f); i += 4; */ |
|
2609
|
125644
|
|
|
|
|
|
d4 = e + d/f; |
|
2610
|
125644
|
50
|
|
|
|
|
if (d4 > 9999) { |
|
2611
|
0
|
|
|
|
|
|
d4 -= 10000; |
|
2612
|
0
|
0
|
|
|
|
|
for (b = i; out[--b] == '9';) out[b] = '0'; |
|
2613
|
0
|
|
|
|
|
|
out[b]++; |
|
2614
|
|
|
|
|
|
|
} |
|
2615
|
125644
|
|
|
|
|
|
d3 = d4/10; d2 = d3/10; d1 = d2/10; |
|
2616
|
125644
|
|
|
|
|
|
out[i++] = '0' + (char)d1; |
|
2617
|
125644
|
|
|
|
|
|
out[i++] = '0' + (char)(d2-d1*10); |
|
2618
|
125644
|
|
|
|
|
|
out[i++] = '0' + (char)(d3-d2*10); |
|
2619
|
125644
|
|
|
|
|
|
out[i++] = '0' + (char)(d4-d3*10); |
|
2620
|
|
|
|
|
|
|
} |
|
2621
|
972
|
|
|
|
|
|
Safefree(a); |
|
2622
|
972
|
100
|
|
|
|
|
if (out[digits-1] >= '5') out[digits-2]++; /* Round */ |
|
2623
|
1042
|
100
|
|
|
|
|
for (i = digits-2; out[i] == '9'+1; i--) /* Keep rounding */ |
|
2624
|
70
|
|
|
|
|
|
{ out[i] = '0'; out[i-1]++; } |
|
2625
|
972
|
|
|
|
|
|
out[digits-1] = '\0'; /* trailing null overwrites rounding digit */ |
|
2626
|
972
|
|
|
|
|
|
*out-- = '.'; /* "331415..." => "3.1415..." */ |
|
2627
|
972
|
|
|
|
|
|
return out; |
|
2628
|
|
|
|
|
|
|
} |
|
2629
|
|
|
|
|
|
|
|
|
2630
|
338
|
|
|
|
|
|
static int strnum_parse(const char **sp, STRLEN *slen) |
|
2631
|
|
|
|
|
|
|
{ |
|
2632
|
338
|
|
|
|
|
|
const char* s = *sp; |
|
2633
|
338
|
|
|
|
|
|
STRLEN i = 0, len = *slen; |
|
2634
|
338
|
|
|
|
|
|
int neg = 0; |
|
2635
|
|
|
|
|
|
|
|
|
2636
|
338
|
50
|
|
|
|
|
if (s != 0 && len > 0) { |
|
|
|
50
|
|
|
|
|
|
|
2637
|
338
|
|
|
|
|
|
neg = (s[0] == '-'); |
|
2638
|
338
|
100
|
|
|
|
|
if (s[0] == '-' || s[0] == '+') { s++; len--; } |
|
|
|
50
|
|
|
|
|
|
|
2639
|
346
|
100
|
|
|
|
|
while (len > 0 && *s == '0') { s++; len--; } |
|
|
|
100
|
|
|
|
|
|
|
2640
|
338
|
100
|
|
|
|
|
if (len == 0) { s--; len = 1; neg = 0; } /* value is 0 */ |
|
2641
|
7574
|
100
|
|
|
|
|
for (i = 0; i < len; i++) |
|
2642
|
7236
|
50
|
|
|
|
|
if (!isDIGIT(s[i])) |
|
2643
|
0
|
|
|
|
|
|
break; |
|
2644
|
|
|
|
|
|
|
} |
|
2645
|
338
|
50
|
|
|
|
|
if (s == 0 || len == 0 || i < len) croak("Parameter must be an integer"); |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
2646
|
338
|
|
|
|
|
|
*sp = s; |
|
2647
|
338
|
|
|
|
|
|
*slen = len; |
|
2648
|
338
|
|
|
|
|
|
return neg; |
|
2649
|
|
|
|
|
|
|
} |
|
2650
|
167
|
|
|
|
|
|
int strnum_cmp(const char* a, STRLEN alen, const char* b, STRLEN blen) { |
|
2651
|
|
|
|
|
|
|
STRLEN i; |
|
2652
|
167
|
|
|
|
|
|
int aneg = strnum_parse(&a, &alen); |
|
2653
|
167
|
|
|
|
|
|
int bneg = strnum_parse(&b, &blen); |
|
2654
|
167
|
100
|
|
|
|
|
if (aneg != bneg) return (bneg) ? 1 : -1; |
|
|
|
100
|
|
|
|
|
|
|
2655
|
128
|
100
|
|
|
|
|
if (aneg) { /* swap a and b if both negative */ |
|
2656
|
19
|
|
|
|
|
|
const char* t = a; STRLEN tlen = alen; |
|
2657
|
19
|
|
|
|
|
|
a = b; b = t; alen = blen; blen = tlen; |
|
2658
|
|
|
|
|
|
|
} |
|
2659
|
128
|
100
|
|
|
|
|
if (alen != blen) return (alen > blen) ? 1 : -1; |
|
|
|
100
|
|
|
|
|
|
|
2660
|
489
|
100
|
|
|
|
|
for (i = 0; i < blen; i++) |
|
2661
|
482
|
100
|
|
|
|
|
if (a[i] != b[i]) |
|
2662
|
43
|
100
|
|
|
|
|
return (a[i] > b[i]) ? 1 : -1; |
|
2663
|
7
|
|
|
|
|
|
return 0; |
|
2664
|
|
|
|
|
|
|
} |
|
2665
|
|
|
|
|
|
|
|
|
2666
|
|
|
|
|
|
|
/* 1. Perform signed integer validation on b/blen. |
|
2667
|
|
|
|
|
|
|
* 2. Compare to a/alen using min or max based on first arg. |
|
2668
|
|
|
|
|
|
|
* 3. Return 0 to select a, 1 to select b. |
|
2669
|
|
|
|
|
|
|
*/ |
|
2670
|
4
|
|
|
|
|
|
bool strnum_minmax(bool min, const char* a, STRLEN alen, const char* b, STRLEN blen) |
|
2671
|
|
|
|
|
|
|
{ |
|
2672
|
|
|
|
|
|
|
int aneg, bneg; |
|
2673
|
|
|
|
|
|
|
STRLEN i; |
|
2674
|
|
|
|
|
|
|
|
|
2675
|
|
|
|
|
|
|
/* a is checked, process b */ |
|
2676
|
4
|
|
|
|
|
|
bneg = strnum_parse(&b, &blen); |
|
2677
|
|
|
|
|
|
|
|
|
2678
|
4
|
100
|
|
|
|
|
if (a == 0) return 1; |
|
2679
|
|
|
|
|
|
|
|
|
2680
|
2
|
|
|
|
|
|
aneg = (a[0] == '-'); |
|
2681
|
2
|
50
|
|
|
|
|
if (a[0] == '-' || a[0] == '+') { a++; alen--; } |
|
|
|
50
|
|
|
|
|
|
|
2682
|
2
|
50
|
|
|
|
|
while (alen > 0 && *a == '0') { a++; alen--; } |
|
|
|
50
|
|
|
|
|
|
|
2683
|
|
|
|
|
|
|
|
|
2684
|
2
|
50
|
|
|
|
|
if (aneg != bneg) return min ? (bneg == 1) : (aneg == 1); |
|
|
|
0
|
|
|
|
|
|
|
2685
|
2
|
50
|
|
|
|
|
if (aneg == 1) min = !min; |
|
2686
|
2
|
50
|
|
|
|
|
if (alen != blen) return min ? (alen > blen) : (blen > alen); |
|
|
|
0
|
|
|
|
|
|
|
2687
|
|
|
|
|
|
|
|
|
2688
|
2
|
50
|
|
|
|
|
for (i = 0; i < blen; i++) |
|
2689
|
2
|
50
|
|
|
|
|
if (a[i] != b[i]) |
|
2690
|
2
|
100
|
|
|
|
|
return min ? (a[i] > b[i]) : (b[i] > a[i]); |
|
2691
|
0
|
|
|
|
|
|
return 0; /* equal */ |
|
2692
|
|
|
|
|
|
|
} |
|
2693
|
|
|
|
|
|
|
|
|
2694
|
17
|
|
|
|
|
|
bool from_digit_string(UV* rn, const char* s, int base) |
|
2695
|
|
|
|
|
|
|
{ |
|
2696
|
17
|
|
|
|
|
|
UV max, n = 0; |
|
2697
|
|
|
|
|
|
|
int i, len; |
|
2698
|
|
|
|
|
|
|
|
|
2699
|
|
|
|
|
|
|
/* Skip leading -/+ and zeros */ |
|
2700
|
17
|
50
|
|
|
|
|
if (s[0] == '-' || s[0] == '+') s++; |
|
|
|
50
|
|
|
|
|
|
|
2701
|
17
|
50
|
|
|
|
|
while (s[0] == '0') s++; |
|
2702
|
|
|
|
|
|
|
|
|
2703
|
17
|
|
|
|
|
|
len = strlen(s); |
|
2704
|
17
|
|
|
|
|
|
max = (UV_MAX-base+1)/base; |
|
2705
|
|
|
|
|
|
|
|
|
2706
|
505
|
100
|
|
|
|
|
for (i = 0; i < len; i++) { |
|
2707
|
499
|
|
|
|
|
|
const char c = s[i]; |
|
2708
|
499
|
50
|
|
|
|
|
int d = !isalnum(c) ? 255 : (c <= '9') ? c-'0' : (c <= 'Z') ? c-'A'+10 : c-'a'+10; |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
2709
|
499
|
50
|
|
|
|
|
if (d >= base) croak("Invalid digit for base %d", base); |
|
2710
|
499
|
100
|
|
|
|
|
if (n > max) return 0; /* Overflow */ |
|
2711
|
488
|
|
|
|
|
|
n = n * base + d; |
|
2712
|
|
|
|
|
|
|
} |
|
2713
|
6
|
|
|
|
|
|
*rn = n; |
|
2714
|
6
|
|
|
|
|
|
return 1; |
|
2715
|
|
|
|
|
|
|
} |
|
2716
|
|
|
|
|
|
|
|
|
2717
|
14
|
|
|
|
|
|
bool from_digit_to_UV(UV* rn, const UV* r, int len, int base) |
|
2718
|
|
|
|
|
|
|
{ |
|
2719
|
14
|
|
|
|
|
|
UV d, n = 0; |
|
2720
|
|
|
|
|
|
|
int i; |
|
2721
|
14
|
50
|
|
|
|
|
if (len < 0 || len > BITS_PER_WORD) |
|
|
|
50
|
|
|
|
|
|
|
2722
|
0
|
|
|
|
|
|
return 0; |
|
2723
|
93
|
100
|
|
|
|
|
for (i = 0; i < len; i++) { |
|
2724
|
80
|
|
|
|
|
|
d = r[i]; |
|
2725
|
80
|
100
|
|
|
|
|
if (n > (UV_MAX-d)/base) break; /* overflow */ |
|
2726
|
79
|
|
|
|
|
|
n = n * base + d; |
|
2727
|
|
|
|
|
|
|
} |
|
2728
|
14
|
|
|
|
|
|
*rn = n; |
|
2729
|
14
|
|
|
|
|
|
return (i >= len); |
|
2730
|
|
|
|
|
|
|
} |
|
2731
|
|
|
|
|
|
|
|
|
2732
|
|
|
|
|
|
|
|
|
2733
|
1
|
|
|
|
|
|
bool from_digit_to_str(char** rstr, const UV* r, int len, int base) |
|
2734
|
|
|
|
|
|
|
{ |
|
2735
|
|
|
|
|
|
|
char *so, *s; |
|
2736
|
|
|
|
|
|
|
int i; |
|
2737
|
|
|
|
|
|
|
|
|
2738
|
1
|
50
|
|
|
|
|
if (len < 0 || !(base == 2 || base == 10 || base == 16)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
2739
|
|
|
|
|
|
|
|
|
2740
|
1
|
50
|
|
|
|
|
if (r[0] >= (UV) base) return 0; /* TODO: We don't apply extended carry */ |
|
2741
|
|
|
|
|
|
|
|
|
2742
|
1
|
|
|
|
|
|
New(0, so, len + 3, char); |
|
2743
|
1
|
|
|
|
|
|
s = so; |
|
2744
|
1
|
50
|
|
|
|
|
if (base == 2 || base == 16) { |
|
|
|
50
|
|
|
|
|
|
|
2745
|
1
|
|
|
|
|
|
*s++ = '0'; |
|
2746
|
1
|
50
|
|
|
|
|
*s++ = (base == 2) ? 'b' : 'x'; |
|
2747
|
|
|
|
|
|
|
} |
|
2748
|
46
|
100
|
|
|
|
|
for (i = 0; i < len; i++) { |
|
2749
|
45
|
|
|
|
|
|
UV d = r[i]; |
|
2750
|
45
|
100
|
|
|
|
|
s[i] = (d < 10) ? '0'+(char)d : 'a'+(char)(d-10); |
|
2751
|
|
|
|
|
|
|
} |
|
2752
|
1
|
|
|
|
|
|
s[len] = '\0'; |
|
2753
|
1
|
|
|
|
|
|
*rstr = so; |
|
2754
|
1
|
|
|
|
|
|
return 1; |
|
2755
|
|
|
|
|
|
|
} |
|
2756
|
|
|
|
|
|
|
|
|
2757
|
163
|
|
|
|
|
|
int to_digit_array(int* bits, UV n, int base, int length) |
|
2758
|
|
|
|
|
|
|
{ |
|
2759
|
|
|
|
|
|
|
int d; |
|
2760
|
|
|
|
|
|
|
|
|
2761
|
163
|
50
|
|
|
|
|
if (base < 2 || length > 128) return -1; |
|
|
|
50
|
|
|
|
|
|
|
2762
|
|
|
|
|
|
|
|
|
2763
|
163
|
100
|
|
|
|
|
if (base == 2) { |
|
2764
|
3881
|
100
|
|
|
|
|
for (d = 0; n; n >>= 1) |
|
2765
|
3728
|
|
|
|
|
|
bits[d++] = n & 1; |
|
2766
|
|
|
|
|
|
|
} else { |
|
2767
|
44
|
100
|
|
|
|
|
for (d = 0; n; n /= base) |
|
2768
|
34
|
|
|
|
|
|
bits[d++] = n % base; |
|
2769
|
|
|
|
|
|
|
} |
|
2770
|
163
|
100
|
|
|
|
|
if (length < 0) length = d; |
|
2771
|
194
|
100
|
|
|
|
|
while (d < length) |
|
2772
|
31
|
|
|
|
|
|
bits[d++] = 0; |
|
2773
|
163
|
|
|
|
|
|
return length; |
|
2774
|
|
|
|
|
|
|
} |
|
2775
|
|
|
|
|
|
|
|
|
2776
|
5
|
|
|
|
|
|
int to_digit_string(char* s, UV n, int base, int length) |
|
2777
|
|
|
|
|
|
|
{ |
|
2778
|
|
|
|
|
|
|
int digits[128]; |
|
2779
|
5
|
|
|
|
|
|
int i, len = to_digit_array(digits, n, base, length); |
|
2780
|
|
|
|
|
|
|
|
|
2781
|
5
|
50
|
|
|
|
|
if (len < 0) return -1; |
|
2782
|
5
|
50
|
|
|
|
|
if (base > 36) croak("invalid base for string: %d", base); |
|
2783
|
|
|
|
|
|
|
|
|
2784
|
35
|
100
|
|
|
|
|
for (i = 0; i < len; i++) { |
|
2785
|
30
|
|
|
|
|
|
int dig = digits[len-i-1]; |
|
2786
|
30
|
100
|
|
|
|
|
s[i] = (dig < 10) ? '0'+(char)dig : 'a'+(char)(dig-10); |
|
2787
|
|
|
|
|
|
|
} |
|
2788
|
5
|
|
|
|
|
|
s[len] = '\0'; |
|
2789
|
5
|
|
|
|
|
|
return len; |
|
2790
|
|
|
|
|
|
|
} |
|
2791
|
|
|
|
|
|
|
|
|
2792
|
8
|
|
|
|
|
|
int to_string_128(char str[40], IV hi, UV lo) |
|
2793
|
|
|
|
|
|
|
{ |
|
2794
|
8
|
|
|
|
|
|
int i, slen = 0, isneg = 0; |
|
2795
|
|
|
|
|
|
|
|
|
2796
|
8
|
100
|
|
|
|
|
if (hi < 0) { |
|
2797
|
5
|
|
|
|
|
|
isneg = 1; |
|
2798
|
5
|
100
|
|
|
|
|
if (lo == 0) { |
|
2799
|
2
|
|
|
|
|
|
hi = -hi; |
|
2800
|
|
|
|
|
|
|
} else { |
|
2801
|
3
|
|
|
|
|
|
hi = -(hi+1); |
|
2802
|
3
|
|
|
|
|
|
lo = UV_MAX - lo + 1; |
|
2803
|
|
|
|
|
|
|
} |
|
2804
|
|
|
|
|
|
|
} |
|
2805
|
|
|
|
|
|
|
#if BITS_PER_WORD == 64 && HAVE_UINT128 |
|
2806
|
|
|
|
|
|
|
{ |
|
2807
|
8
|
|
|
|
|
|
uint128_t dd, sum = (((uint128_t) hi) << 64) + lo; |
|
2808
|
|
|
|
|
|
|
do { |
|
2809
|
159
|
|
|
|
|
|
dd = sum / 10; |
|
2810
|
159
|
|
|
|
|
|
str[slen++] = '0' + (char)(sum - dd*10); |
|
2811
|
159
|
|
|
|
|
|
sum = dd; |
|
2812
|
159
|
100
|
|
|
|
|
} while (sum); |
|
2813
|
|
|
|
|
|
|
} |
|
2814
|
|
|
|
|
|
|
#else |
|
2815
|
|
|
|
|
|
|
{ |
|
2816
|
|
|
|
|
|
|
UV d, r; |
|
2817
|
|
|
|
|
|
|
uint32_t a[4]; |
|
2818
|
|
|
|
|
|
|
a[0] = hi >> (BITS_PER_WORD/2); |
|
2819
|
|
|
|
|
|
|
a[1] = hi & (UV_MAX >> (BITS_PER_WORD/2)); |
|
2820
|
|
|
|
|
|
|
a[2] = lo >> (BITS_PER_WORD/2); |
|
2821
|
|
|
|
|
|
|
a[3] = lo & (UV_MAX >> (BITS_PER_WORD/2)); |
|
2822
|
|
|
|
|
|
|
do { |
|
2823
|
|
|
|
|
|
|
r = a[0]; |
|
2824
|
|
|
|
|
|
|
d = r/10; r = ((r-d*10) << (BITS_PER_WORD/2)) + a[1]; a[0] = d; |
|
2825
|
|
|
|
|
|
|
d = r/10; r = ((r-d*10) << (BITS_PER_WORD/2)) + a[2]; a[1] = d; |
|
2826
|
|
|
|
|
|
|
d = r/10; r = ((r-d*10) << (BITS_PER_WORD/2)) + a[3]; a[2] = d; |
|
2827
|
|
|
|
|
|
|
d = r/10; r = r-d*10; a[3] = d; |
|
2828
|
|
|
|
|
|
|
str[slen++] = '0'+(r%10); |
|
2829
|
|
|
|
|
|
|
} while (a[0] || a[1] || a[2] || a[3]); |
|
2830
|
|
|
|
|
|
|
} |
|
2831
|
|
|
|
|
|
|
#endif |
|
2832
|
|
|
|
|
|
|
/* Reverse the order */ |
|
2833
|
87
|
100
|
|
|
|
|
for (i=0; i < slen/2; i++) { |
|
2834
|
79
|
|
|
|
|
|
char t=str[i]; |
|
2835
|
79
|
|
|
|
|
|
str[i]=str[slen-i-1]; |
|
2836
|
79
|
|
|
|
|
|
str[slen-i-1] = t; |
|
2837
|
|
|
|
|
|
|
} |
|
2838
|
|
|
|
|
|
|
/* Prepend a negative sign if needed */ |
|
2839
|
8
|
100
|
|
|
|
|
if (isneg) { |
|
2840
|
104
|
100
|
|
|
|
|
for (i = slen; i > 0; i--) |
|
2841
|
99
|
|
|
|
|
|
str[i] = str[i-1]; |
|
2842
|
5
|
|
|
|
|
|
str[0] = '-'; |
|
2843
|
5
|
|
|
|
|
|
slen++; |
|
2844
|
|
|
|
|
|
|
} |
|
2845
|
|
|
|
|
|
|
/* Add terminator */ |
|
2846
|
8
|
|
|
|
|
|
str[slen] = '\0'; |
|
2847
|
8
|
|
|
|
|
|
return slen; |
|
2848
|
|
|
|
|
|
|
} |
|
2849
|
|
|
|
|
|
|
|
|
2850
|
|
|
|
|
|
|
#if BITS_PER_WORD == 64 |
|
2851
|
|
|
|
|
|
|
#define MAX_FIB_LEN 92 |
|
2852
|
|
|
|
|
|
|
#define MAX_FIB_STR "10100101000100000101000100010010001001000000001001000100100010101000100000101000101000001010" |
|
2853
|
|
|
|
|
|
|
#else |
|
2854
|
|
|
|
|
|
|
#define MAX_FIB_LEN 46 |
|
2855
|
|
|
|
|
|
|
#define MAX_FIB_STR "1010001000010101000101000100000001000100100100" |
|
2856
|
|
|
|
|
|
|
#endif |
|
2857
|
|
|
|
|
|
|
#define MAX_FIB_VAL (MAX_FIB_LEN+1) |
|
2858
|
|
|
|
|
|
|
|
|
2859
|
|
|
|
|
|
|
/* 0 = bad, -1 = not canonical, 1 = good, 2 = ok but out of UV range */ |
|
2860
|
27
|
|
|
|
|
|
int validate_zeckendorf(const char* str) |
|
2861
|
|
|
|
|
|
|
{ |
|
2862
|
|
|
|
|
|
|
int i; |
|
2863
|
27
|
50
|
|
|
|
|
if (str == 0) |
|
2864
|
0
|
|
|
|
|
|
return 0; |
|
2865
|
27
|
100
|
|
|
|
|
if (str[0] != '1') |
|
2866
|
1
|
50
|
|
|
|
|
return (str[0] == '0' && str[1] == '\0'); |
|
|
|
50
|
|
|
|
|
|
|
2867
|
|
|
|
|
|
|
/* str[0] = 1 */ |
|
2868
|
397
|
100
|
|
|
|
|
for (i = 1; str[i] != '\0'; i++) { |
|
2869
|
371
|
100
|
|
|
|
|
if (str[i] == '1') { |
|
2870
|
104
|
50
|
|
|
|
|
if (str[i-1] == '1') |
|
2871
|
0
|
|
|
|
|
|
return -1; |
|
2872
|
267
|
50
|
|
|
|
|
} else if (str[i] != '0') { |
|
2873
|
0
|
|
|
|
|
|
return 0; |
|
2874
|
|
|
|
|
|
|
} |
|
2875
|
|
|
|
|
|
|
} |
|
2876
|
|
|
|
|
|
|
/* Valid number. Check if in range. */ |
|
2877
|
26
|
100
|
|
|
|
|
if (i > MAX_FIB_LEN || (i == MAX_FIB_LEN && strcmp(str, MAX_FIB_STR) > 0)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
2878
|
1
|
|
|
|
|
|
return 2; |
|
2879
|
25
|
|
|
|
|
|
return 1; |
|
2880
|
|
|
|
|
|
|
} |
|
2881
|
|
|
|
|
|
|
|
|
2882
|
26
|
|
|
|
|
|
UV from_zeckendorf(const char* str) |
|
2883
|
|
|
|
|
|
|
{ |
|
2884
|
|
|
|
|
|
|
int i, len; |
|
2885
|
26
|
|
|
|
|
|
UV n, fa = 0, fb = 1, fc = 1; /* fc = fib(2) */ |
|
2886
|
|
|
|
|
|
|
|
|
2887
|
26
|
50
|
|
|
|
|
if (str == 0) return 0; |
|
2888
|
286
|
100
|
|
|
|
|
for (len = 0; len < MAX_FIB_LEN && str[len] != '\0'; len++) |
|
|
|
100
|
|
|
|
|
|
|
2889
|
260
|
100
|
|
|
|
|
if (str[len] != '0' && str[len] != '1') |
|
|
|
50
|
|
|
|
|
|
|
2890
|
0
|
|
|
|
|
|
return 0; |
|
2891
|
26
|
50
|
|
|
|
|
if (len == 0 || len > MAX_FIB_LEN) return 0; |
|
|
|
50
|
|
|
|
|
|
|
2892
|
26
|
|
|
|
|
|
n = (str[len-1] == '1'); |
|
2893
|
260
|
100
|
|
|
|
|
for (i = len-2; i >= 0; i--) { |
|
2894
|
234
|
|
|
|
|
|
fa = fb; fb = fc; fc = fa+fb; /* Advance */ |
|
2895
|
234
|
100
|
|
|
|
|
if (str[i] == '1') n += fc; |
|
2896
|
|
|
|
|
|
|
} |
|
2897
|
26
|
|
|
|
|
|
return n; |
|
2898
|
|
|
|
|
|
|
} |
|
2899
|
|
|
|
|
|
|
|
|
2900
|
27
|
|
|
|
|
|
char* to_zeckendorf(UV n) |
|
2901
|
|
|
|
|
|
|
{ |
|
2902
|
|
|
|
|
|
|
char *str; |
|
2903
|
27
|
|
|
|
|
|
int i, k, spos = 0; |
|
2904
|
27
|
|
|
|
|
|
UV fa = 0, fb = 1, fc = 1; /* fc = fib(2) */ |
|
2905
|
|
|
|
|
|
|
|
|
2906
|
27
|
|
|
|
|
|
New(0, str, MAX_FIB_LEN+1, char); |
|
2907
|
27
|
100
|
|
|
|
|
if (n == 0) { |
|
2908
|
1
|
|
|
|
|
|
str[spos++] = '0'; |
|
2909
|
|
|
|
|
|
|
} else { |
|
2910
|
26
|
|
|
|
|
|
UV rn = n; |
|
2911
|
292
|
100
|
|
|
|
|
for (k = 2; k <= MAX_FIB_VAL && fc <= rn; k++) { |
|
|
|
100
|
|
|
|
|
|
|
2912
|
266
|
|
|
|
|
|
fa = fb; fb = fc; fc = fa+fb; /* Advance: fc = fib(k) */ |
|
2913
|
|
|
|
|
|
|
} |
|
2914
|
292
|
100
|
|
|
|
|
for (i = k-1; i >= 2; i--) { |
|
2915
|
266
|
|
|
|
|
|
fc = fb; fb = fa; fa = fc-fb; /* Reverse: fc = fib(i) */ |
|
2916
|
266
|
100
|
|
|
|
|
str[spos++] = '0' + (fc <= rn); |
|
2917
|
266
|
100
|
|
|
|
|
if (fc <= rn) rn -= fc; |
|
2918
|
|
|
|
|
|
|
} |
|
2919
|
|
|
|
|
|
|
} |
|
2920
|
27
|
|
|
|
|
|
str[spos++] = '\0'; |
|
2921
|
|
|
|
|
|
|
#if 0 |
|
2922
|
|
|
|
|
|
|
if (validate_zeckendorf(str) != 1) croak("to_zeckendorf bad for %lu\n",n); |
|
2923
|
|
|
|
|
|
|
if (from_zeckendorf(str) != n) croak("to_zeckendorf wrong for %lu\n",n); |
|
2924
|
|
|
|
|
|
|
#endif |
|
2925
|
27
|
|
|
|
|
|
return str; |
|
2926
|
|
|
|
|
|
|
} |
|
2927
|
|
|
|
|
|
|
|
|
2928
|
|
|
|
|
|
|
|
|
2929
|
|
|
|
|
|
|
/* Oddball primality test. |
|
2930
|
|
|
|
|
|
|
* In this file rather than primality.c because it uses factoring (!). |
|
2931
|
|
|
|
|
|
|
* Algorithm from Charles R Greathouse IV, 2015 */ |
|
2932
|
472642
|
|
|
|
|
|
static INLINE uint32_t _catalan_v32(uint32_t n, uint32_t p) { |
|
2933
|
472642
|
|
|
|
|
|
uint32_t s = 0; |
|
2934
|
946183
|
100
|
|
|
|
|
while (n /= p) s += n % 2; |
|
2935
|
472642
|
|
|
|
|
|
return s; |
|
2936
|
|
|
|
|
|
|
} |
|
2937
|
0
|
|
|
|
|
|
static INLINE uint32_t _catalan_v(UV n, UV p) { |
|
2938
|
0
|
|
|
|
|
|
uint32_t s = 0; |
|
2939
|
0
|
0
|
|
|
|
|
while (n /= p) s += n % 2; |
|
2940
|
0
|
|
|
|
|
|
return s; |
|
2941
|
|
|
|
|
|
|
} |
|
2942
|
901451
|
|
|
|
|
|
static UV _catalan_mult(UV m, UV p, UV n, UV a) { |
|
2943
|
901451
|
100
|
|
|
|
|
if (p > a) { |
|
2944
|
428809
|
|
|
|
|
|
m = mulmod(m, p, n); |
|
2945
|
|
|
|
|
|
|
} else { |
|
2946
|
472642
|
50
|
|
|
|
|
UV pow = (n <= 4294967295UL) ? _catalan_v32(a<<1,p) : _catalan_v(a<<1,p); |
|
2947
|
472642
|
|
|
|
|
|
m = (pow == 0) ? m |
|
2948
|
658853
|
100
|
|
|
|
|
: (pow == 1) ? mulmod(m,p,n) |
|
2949
|
186211
|
100
|
|
|
|
|
: mulmod(m,powmod(p,pow,n),n); |
|
2950
|
|
|
|
|
|
|
} |
|
2951
|
901451
|
|
|
|
|
|
return m; |
|
2952
|
|
|
|
|
|
|
} |
|
2953
|
5
|
|
|
|
|
|
static int _catalan_vtest(UV n, UV p) { |
|
2954
|
18
|
100
|
|
|
|
|
while (n /= p) |
|
2955
|
13
|
50
|
|
|
|
|
if (n % 2) |
|
2956
|
0
|
|
|
|
|
|
return 1; |
|
2957
|
5
|
|
|
|
|
|
return 0; |
|
2958
|
|
|
|
|
|
|
} |
|
2959
|
3
|
|
|
|
|
|
bool is_catalan_pseudoprime(UV n) { |
|
2960
|
|
|
|
|
|
|
UV m, a; |
|
2961
|
|
|
|
|
|
|
|
|
2962
|
3
|
50
|
|
|
|
|
if (n < 2 || ((n % 2) == 0 && n != 2)) return 0; |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2963
|
3
|
50
|
|
|
|
|
if (is_prob_prime(n)) return 1; |
|
2964
|
|
|
|
|
|
|
|
|
2965
|
3
|
|
|
|
|
|
m = 1; |
|
2966
|
3
|
|
|
|
|
|
a = n >> 1; |
|
2967
|
|
|
|
|
|
|
/* |
|
2968
|
|
|
|
|
|
|
* Ideally we could use some of the requirements for a mod 4/8/64 here: |
|
2969
|
|
|
|
|
|
|
* http://www.combinatorics.net/conf/Z60/sp/sp/Shu-Chung%20Liu.pdf |
|
2970
|
|
|
|
|
|
|
* But, how do we make +/-2 = X mod n into a solution for x = X mod 8? |
|
2971
|
|
|
|
|
|
|
* |
|
2972
|
|
|
|
|
|
|
* We could also exploit the exhaustive testing that shows there only |
|
2973
|
|
|
|
|
|
|
* exist three below 1e10: 5907, 1194649, and 12327121. |
|
2974
|
|
|
|
|
|
|
*/ |
|
2975
|
|
|
|
|
|
|
{ |
|
2976
|
|
|
|
|
|
|
uint32_t i; |
|
2977
|
3
|
|
|
|
|
|
factored_t nf = factorint(n); |
|
2978
|
|
|
|
|
|
|
#if BITS_PER_WORD == 32 |
|
2979
|
|
|
|
|
|
|
if (nf.nfactors == 2) return 0; /* Page 9, all 32-bit semiprimes */ |
|
2980
|
|
|
|
|
|
|
#else |
|
2981
|
3
|
50
|
|
|
|
|
if (nf.nfactors == 2) { /* Conditions from Aebi and Cairns (2008) */ |
|
2982
|
0
|
0
|
|
|
|
|
if (n < UVCONST(10000000000)) return 0; /* Page 9 */ |
|
2983
|
0
|
0
|
|
|
|
|
if (2*nf.f[0]+1 >= nf.f[1]) return 0; /* Corollary 2 and 3 */ |
|
2984
|
|
|
|
|
|
|
} |
|
2985
|
|
|
|
|
|
|
#endif |
|
2986
|
|
|
|
|
|
|
/* Test every factor */ |
|
2987
|
8
|
100
|
|
|
|
|
for (i = 0; i < nf.nfactors; i++) { |
|
2988
|
5
|
50
|
|
|
|
|
if (_catalan_vtest(a << 1, nf.f[i])) |
|
2989
|
0
|
|
|
|
|
|
return 0; |
|
2990
|
|
|
|
|
|
|
} |
|
2991
|
|
|
|
|
|
|
} |
|
2992
|
|
|
|
|
|
|
{ |
|
2993
|
|
|
|
|
|
|
UV seg_base, seg_low, seg_high; |
|
2994
|
|
|
|
|
|
|
unsigned char* segment; |
|
2995
|
|
|
|
|
|
|
void* ctx; |
|
2996
|
3
|
|
|
|
|
|
m = _catalan_mult(m, 2, n, a); |
|
2997
|
3
|
|
|
|
|
|
m = _catalan_mult(m, 3, n, a); |
|
2998
|
3
|
|
|
|
|
|
m = _catalan_mult(m, 5, n, a); |
|
2999
|
3
|
|
|
|
|
|
ctx = start_segment_primes(7, n, &segment); |
|
3000
|
19
|
100
|
|
|
|
|
while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) { |
|
3001
|
957825
|
50
|
|
|
|
|
START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3002
|
901442
|
|
|
|
|
|
m = _catalan_mult(m, p, n, a); |
|
3003
|
56367
|
|
|
|
|
|
} END_DO_FOR_EACH_SIEVE_PRIME |
|
3004
|
|
|
|
|
|
|
} |
|
3005
|
3
|
|
|
|
|
|
end_segment_primes(ctx); |
|
3006
|
|
|
|
|
|
|
} |
|
3007
|
3
|
100
|
|
|
|
|
return (a & 1) ? (m==(n-1)) : (m==1); |
|
3008
|
|
|
|
|
|
|
} |
|
3009
|
|
|
|
|
|
|
|
|
3010
|
|
|
|
|
|
|
/* If we have fast CTZ, use this GCD. See Brent Alg V and FLINT Abhinav Baid */ |
|
3011
|
119975
|
|
|
|
|
|
UV gcdz(UV x, UV y) { |
|
3012
|
|
|
|
|
|
|
UV f, x2, y2; |
|
3013
|
|
|
|
|
|
|
|
|
3014
|
119975
|
100
|
|
|
|
|
if (x == 0) return y; |
|
3015
|
|
|
|
|
|
|
|
|
3016
|
119950
|
100
|
|
|
|
|
if (y & 1) { /* Optimize y odd */ |
|
3017
|
66680
|
50
|
|
|
|
|
x >>= ctz(x); |
|
3018
|
981368
|
100
|
|
|
|
|
while (x != y) { |
|
3019
|
914688
|
100
|
|
|
|
|
if (x < y) { y -= x; y >>= ctz(y); } |
|
|
|
50
|
|
|
|
|
|
|
3020
|
626861
|
50
|
|
|
|
|
else { x -= y; x >>= ctz(x); } |
|
3021
|
|
|
|
|
|
|
} |
|
3022
|
66680
|
|
|
|
|
|
return x; |
|
3023
|
|
|
|
|
|
|
} |
|
3024
|
|
|
|
|
|
|
|
|
3025
|
53270
|
100
|
|
|
|
|
if (y == 0) return x; |
|
3026
|
|
|
|
|
|
|
|
|
3027
|
|
|
|
|
|
|
/* Alternately: f = ctz(x|y); x >>= ctz(x); y >>= ctz(y); */ |
|
3028
|
53269
|
50
|
|
|
|
|
x2 = ctz(x); |
|
3029
|
53269
|
50
|
|
|
|
|
y2 = ctz(y); |
|
3030
|
53269
|
|
|
|
|
|
f = (x2 <= y2) ? x2 : y2; |
|
3031
|
53269
|
|
|
|
|
|
x >>= x2; |
|
3032
|
53269
|
|
|
|
|
|
y >>= y2; |
|
3033
|
|
|
|
|
|
|
|
|
3034
|
527205
|
100
|
|
|
|
|
while (x != y) { |
|
3035
|
473936
|
100
|
|
|
|
|
if (x < y) { |
|
3036
|
128159
|
|
|
|
|
|
y -= x; |
|
3037
|
128159
|
50
|
|
|
|
|
y >>= ctz(y); |
|
3038
|
|
|
|
|
|
|
} else { |
|
3039
|
345777
|
|
|
|
|
|
x -= y; |
|
3040
|
345777
|
50
|
|
|
|
|
x >>= ctz(x); |
|
3041
|
|
|
|
|
|
|
} |
|
3042
|
|
|
|
|
|
|
} |
|
3043
|
53269
|
|
|
|
|
|
return x << f; |
|
3044
|
|
|
|
|
|
|
} |
|
3045
|
|
|
|
|
|
|
|
|
3046
|
|
|
|
|
|
|
/* The intermediate values are so large that we can only stay in 64-bit |
|
3047
|
|
|
|
|
|
|
* up to 53 or so using the divisor_sum calculations. So just use a table. |
|
3048
|
|
|
|
|
|
|
* Save space by just storing the 32-bit values. */ |
|
3049
|
|
|
|
|
|
|
static const int32_t tau_table[] = { |
|
3050
|
|
|
|
|
|
|
0,1,-24,252,-1472,4830,-6048,-16744,84480,-113643,-115920,534612,-370944,-577738,401856,1217160,987136,-6905934,2727432,10661420,-7109760,-4219488,-12830688,18643272,21288960,-25499225,13865712,-73279080,24647168,128406630,-29211840,-52843168,-196706304,134722224,165742416,-80873520,167282496,-182213314,-255874080,-145589976,408038400,308120442,101267712,-17125708,-786948864,-548895690,-447438528 |
|
3051
|
|
|
|
|
|
|
}; |
|
3052
|
|
|
|
|
|
|
#define NTAU (sizeof(tau_table)/sizeof(tau_table[0])) |
|
3053
|
10
|
|
|
|
|
|
IV ramanujan_tau(UV n) { |
|
3054
|
10
|
100
|
|
|
|
|
return (n < NTAU) ? tau_table[n] : 0; |
|
3055
|
|
|
|
|
|
|
} |
|
3056
|
|
|
|
|
|
|
|
|
3057
|
401
|
|
|
|
|
|
static UV _count_class_div(UV s, UV b2) { |
|
3058
|
401
|
|
|
|
|
|
UV h = 0, i, ndivisors, *divs, lim; |
|
3059
|
|
|
|
|
|
|
|
|
3060
|
401
|
|
|
|
|
|
lim = isqrt(b2); |
|
3061
|
401
|
100
|
|
|
|
|
if (lim*lim == b2) lim--; |
|
3062
|
401
|
100
|
|
|
|
|
if (s > lim) return 0; |
|
3063
|
|
|
|
|
|
|
|
|
3064
|
359
|
100
|
|
|
|
|
if ((lim-s) < 70) { /* Iterate looking for divisors */ |
|
3065
|
7096
|
100
|
|
|
|
|
for (i = s; i <= lim; i++) |
|
3066
|
6762
|
100
|
|
|
|
|
if (b2 % i == 0) |
|
3067
|
105
|
|
|
|
|
|
h++; |
|
3068
|
|
|
|
|
|
|
} else { /* Walk through all the divisors */ |
|
3069
|
25
|
|
|
|
|
|
divs = divisor_list(b2, &ndivisors, lim); |
|
3070
|
56
|
100
|
|
|
|
|
for (i = 0; i < ndivisors && divs[i] <= lim; i++) |
|
|
|
50
|
|
|
|
|
|
|
3071
|
31
|
100
|
|
|
|
|
if (divs[i] >= s) |
|
3072
|
6
|
|
|
|
|
|
h++; |
|
3073
|
25
|
|
|
|
|
|
Safefree(divs); |
|
3074
|
|
|
|
|
|
|
} |
|
3075
|
359
|
|
|
|
|
|
return h; |
|
3076
|
|
|
|
|
|
|
} |
|
3077
|
|
|
|
|
|
|
|
|
3078
|
|
|
|
|
|
|
/* Returns 12 * H(n). See Cohen 5.3.5 or Pari/GP. |
|
3079
|
|
|
|
|
|
|
* Pari/GP uses a different method for n > 500000, which is quite a bit |
|
3080
|
|
|
|
|
|
|
* faster, but assumes the GRH. */ |
|
3081
|
73
|
|
|
|
|
|
IV hclassno(UV n) { |
|
3082
|
73
|
|
|
|
|
|
UV nmod4 = n % 4, b2, b, h; |
|
3083
|
|
|
|
|
|
|
int square; |
|
3084
|
|
|
|
|
|
|
|
|
3085
|
73
|
100
|
|
|
|
|
if (n == 0) return -1; |
|
3086
|
72
|
100
|
|
|
|
|
if (nmod4 == 1 || nmod4 == 2) return 0; |
|
|
|
100
|
|
|
|
|
|
|
3087
|
70
|
100
|
|
|
|
|
if (n == 3) return 4; |
|
3088
|
|
|
|
|
|
|
|
|
3089
|
69
|
|
|
|
|
|
b = n & 1; |
|
3090
|
69
|
|
|
|
|
|
b2 = (n+1) >> 2; |
|
3091
|
69
|
|
|
|
|
|
square = is_perfect_square(b2); |
|
3092
|
|
|
|
|
|
|
|
|
3093
|
69
|
|
|
|
|
|
h = divisor_sum(b2,0) >> 1; |
|
3094
|
69
|
100
|
|
|
|
|
if (b == 1) |
|
3095
|
18
|
|
|
|
|
|
h = 1 + square + ((h - 1) << 1); |
|
3096
|
69
|
|
|
|
|
|
b += 2; |
|
3097
|
|
|
|
|
|
|
|
|
3098
|
470
|
100
|
|
|
|
|
for (; b2 = (n + b*b) >> 2, 3*b2 < n; b += 2) { |
|
3099
|
802
|
|
|
|
|
|
h += (b2 % b == 0) |
|
3100
|
401
|
|
|
|
|
|
+ is_perfect_square(b2) |
|
3101
|
401
|
|
|
|
|
|
+ (_count_class_div(b+1, b2) << 1); |
|
3102
|
|
|
|
|
|
|
} |
|
3103
|
69
|
100
|
|
|
|
|
return 12*h + ((b2*3 == n) ? 4 : square && !(n&1) ? 6 : 0); |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3104
|
|
|
|
|
|
|
} |
|
3105
|
|
|
|
|
|
|
|
|
3106
|
25302
|
|
|
|
|
|
UV polygonal_root(UV n, UV k, bool* overflow) { |
|
3107
|
|
|
|
|
|
|
UV D, R; |
|
3108
|
25302
|
50
|
|
|
|
|
MPUassert(k >= 3, "is_polygonal root < 3"); |
|
3109
|
25302
|
|
|
|
|
|
*overflow = 0; |
|
3110
|
25302
|
100
|
|
|
|
|
if (n <= 1) return n; |
|
3111
|
25254
|
100
|
|
|
|
|
if (k == 4) { |
|
3112
|
|
|
|
|
|
|
uint32_t root; |
|
3113
|
198
|
100
|
|
|
|
|
return is_perfect_square_ret(n,&root) ? root : 0; |
|
3114
|
|
|
|
|
|
|
} |
|
3115
|
25056
|
100
|
|
|
|
|
if (k == 3) { |
|
3116
|
108
|
50
|
|
|
|
|
if (n >= UV_MAX/8) *overflow = 1; |
|
3117
|
108
|
|
|
|
|
|
D = n << 3; |
|
3118
|
108
|
|
|
|
|
|
R = 1; |
|
3119
|
|
|
|
|
|
|
} else { |
|
3120
|
24948
|
50
|
|
|
|
|
if (k > UV_MAX/k || n > UV_MAX/(8*k-16)) *overflow = 1; |
|
|
|
50
|
|
|
|
|
|
|
3121
|
24948
|
|
|
|
|
|
D = (8*k-16) * n; |
|
3122
|
24948
|
|
|
|
|
|
R = (k-4) * (k-4); |
|
3123
|
|
|
|
|
|
|
} |
|
3124
|
25056
|
50
|
|
|
|
|
if (D+R <= D) *overflow = 1; |
|
3125
|
25056
|
|
|
|
|
|
D += R; |
|
3126
|
25056
|
50
|
|
|
|
|
if (*overflow || !is_perfect_square(D)) return 0; |
|
|
|
100
|
|
|
|
|
|
|
3127
|
918
|
|
|
|
|
|
D = isqrt(D) + (k-4); |
|
3128
|
918
|
|
|
|
|
|
R = 2*k - 4; |
|
3129
|
918
|
100
|
|
|
|
|
if ((D % R) != 0) return 0; |
|
3130
|
396
|
|
|
|
|
|
return D/R; |
|
3131
|
|
|
|
|
|
|
} |
|
3132
|
|
|
|
|
|
|
|
|
3133
|
|
|
|
|
|
|
/* |
|
3134
|
|
|
|
|
|
|
# On Mac M1. The combinatorial solution that we use is both slower and |
|
3135
|
|
|
|
|
|
|
# has *much* worse growth than the Rademacher implementation that uses high |
|
3136
|
|
|
|
|
|
|
# precision floating point (e.g. Pari, MPFR, Arb). |
|
3137
|
|
|
|
|
|
|
# |
|
3138
|
|
|
|
|
|
|
# 10^5 10^6 10^7 10^8 10^9 10^10 |
|
3139
|
|
|
|
|
|
|
# Perl-comb 78 ---- |
|
3140
|
|
|
|
|
|
|
# GMP-comb 0.32 44 ---- |
|
3141
|
|
|
|
|
|
|
# Sympy 1.7.1 0.0045 0.018 0.091 0.62 5.3 51 |
|
3142
|
|
|
|
|
|
|
# Pari 2.14 0.00043 0.0018 0.013 0.19 4.5 54 |
|
3143
|
|
|
|
|
|
|
# Bober 0.6 0.00010 0.00085 0.062 0.91 10.9 15 |
|
3144
|
|
|
|
|
|
|
# Arb 2.19 0.00018 0.00044 0.004 0.011 0.031 0.086 |
|
3145
|
|
|
|
|
|
|
# |
|
3146
|
|
|
|
|
|
|
# Arb 2.19 takes only 62 seconds for 10^14. |
|
3147
|
|
|
|
|
|
|
*/ |
|
3148
|
|
|
|
|
|
|
|
|
3149
|
57
|
|
|
|
|
|
UV npartitions(UV n) { |
|
3150
|
|
|
|
|
|
|
UV *part, *pent, i, j, k, d, npart; |
|
3151
|
|
|
|
|
|
|
|
|
3152
|
57
|
100
|
|
|
|
|
if (n <= 3) return (n == 0) ? 1 : n; |
|
|
|
100
|
|
|
|
|
|
|
3153
|
53
|
100
|
|
|
|
|
if (n > ((BITS_PER_WORD == 32) ? 127 : 416)) return 0; /* Overflow */ |
|
3154
|
|
|
|
|
|
|
|
|
3155
|
49
|
|
|
|
|
|
d = isqrt(n+1); |
|
3156
|
49
|
50
|
|
|
|
|
New(0, pent, 2*d+2, UV); |
|
3157
|
49
|
|
|
|
|
|
pent[0] = 0; |
|
3158
|
49
|
|
|
|
|
|
pent[1] = 1; |
|
3159
|
294
|
100
|
|
|
|
|
for (i = 1; i <= d; i++) { |
|
3160
|
245
|
|
|
|
|
|
pent[2*i ] = ( i *(3*i+1)) / 2; |
|
3161
|
245
|
|
|
|
|
|
pent[2*i+1] = ((i+1)*(3*i+2)) / 2; |
|
3162
|
|
|
|
|
|
|
} |
|
3163
|
49
|
50
|
|
|
|
|
New(0, part, n+1, UV); |
|
3164
|
49
|
|
|
|
|
|
part[0] = 1; |
|
3165
|
1675
|
100
|
|
|
|
|
for (j = 1; j <= n; j++) { |
|
3166
|
1626
|
|
|
|
|
|
UV psum = 0; |
|
3167
|
13844
|
100
|
|
|
|
|
for (k = 1; pent[k] <= j; k++) { |
|
3168
|
12218
|
100
|
|
|
|
|
if ((k+1) & 2) psum += part[ j - pent[k] ]; |
|
3169
|
5279
|
|
|
|
|
|
else psum -= part[ j - pent[k] ]; |
|
3170
|
|
|
|
|
|
|
} |
|
3171
|
1626
|
|
|
|
|
|
part[j] = psum; |
|
3172
|
|
|
|
|
|
|
} |
|
3173
|
49
|
|
|
|
|
|
npart = part[n]; |
|
3174
|
49
|
|
|
|
|
|
Safefree(part); |
|
3175
|
49
|
|
|
|
|
|
Safefree(pent); |
|
3176
|
49
|
|
|
|
|
|
return npart; |
|
3177
|
|
|
|
|
|
|
} |
|
3178
|
|
|
|
|
|
|
|
|
3179
|
102
|
|
|
|
|
|
UV consecutive_integer_lcm(UV n) |
|
3180
|
|
|
|
|
|
|
{ |
|
3181
|
|
|
|
|
|
|
UV i, ilcm, sqrtn; |
|
3182
|
|
|
|
|
|
|
|
|
3183
|
102
|
100
|
|
|
|
|
if (n <= 2) return (n == 0) ? 1 : n; |
|
|
|
100
|
|
|
|
|
|
|
3184
|
|
|
|
|
|
|
|
|
3185
|
99
|
|
|
|
|
|
ilcm = 1; |
|
3186
|
99
|
|
|
|
|
|
sqrtn = isqrt(n); |
|
3187
|
1186
|
50
|
|
|
|
|
for (i = 1; i < NPRIMES_TINY; i++) { |
|
3188
|
1186
|
|
|
|
|
|
uint32_t p = primes_tiny[i]; |
|
3189
|
1186
|
100
|
|
|
|
|
if (p > n) break; |
|
3190
|
1142
|
100
|
|
|
|
|
if (p <= sqrtn) p = ipow(p, logint(n,p)); |
|
3191
|
1142
|
100
|
|
|
|
|
if (ilcm > UV_MAX/p) return 0; |
|
3192
|
1087
|
|
|
|
|
|
ilcm *= p; |
|
3193
|
|
|
|
|
|
|
} |
|
3194
|
44
|
|
|
|
|
|
return ilcm; |
|
3195
|
|
|
|
|
|
|
} |
|
3196
|
|
|
|
|
|
|
|
|
3197
|
64
|
|
|
|
|
|
UV frobenius_number(UV* A, uint32_t alen) |
|
3198
|
|
|
|
|
|
|
{ |
|
3199
|
|
|
|
|
|
|
UV g, i, j, max, *N, nlen; |
|
3200
|
|
|
|
|
|
|
|
|
3201
|
64
|
100
|
|
|
|
|
if (alen <= 1) return 0; |
|
3202
|
63
|
|
|
|
|
|
sort_uv_array(A, alen); |
|
3203
|
63
|
50
|
|
|
|
|
if (A[0] <= 1) return 0; |
|
3204
|
|
|
|
|
|
|
|
|
3205
|
435
|
100
|
|
|
|
|
for (g = A[0], i = 1; i < alen; i++) |
|
3206
|
372
|
|
|
|
|
|
g = gcd_ui(g, A[i]); |
|
3207
|
63
|
100
|
|
|
|
|
if (g != 1) croak("Frobenius number set must be coprime"); |
|
3208
|
|
|
|
|
|
|
|
|
3209
|
62
|
100
|
|
|
|
|
if (UV_MAX/A[0] < A[1]) return UV_MAX; /* Overflow */ |
|
3210
|
|
|
|
|
|
|
|
|
3211
|
60
|
100
|
|
|
|
|
if (alen == 2) |
|
3212
|
1
|
|
|
|
|
|
return A[0] * A[1] - A[0] - A[1]; |
|
3213
|
|
|
|
|
|
|
|
|
3214
|
|
|
|
|
|
|
/* Algorithm "Round Robin" by Böcker and Lipták |
|
3215
|
|
|
|
|
|
|
* |
|
3216
|
|
|
|
|
|
|
* https://bio.informatik.uni-jena.de/wp/wp-content/uploads/2024/01/BoeckerLiptak_FastSimpleAlgorithm_reprint_2007.pdf |
|
3217
|
|
|
|
|
|
|
* |
|
3218
|
|
|
|
|
|
|
* This is the basic version, not the optimized one. It's quite fast |
|
3219
|
|
|
|
|
|
|
* in general, but the time is more or less O(A[0] * alen) and uses |
|
3220
|
|
|
|
|
|
|
* A[0] * sizeof(UV) memory. This means it's not going to work with very |
|
3221
|
|
|
|
|
|
|
* large inputs, where something like DQQDU would work much better. |
|
3222
|
|
|
|
|
|
|
* |
|
3223
|
|
|
|
|
|
|
* See https://www.combinatorics.org/ojs/index.php/eljc/article/view/v12i1r27/pdf |
|
3224
|
|
|
|
|
|
|
*/ |
|
3225
|
|
|
|
|
|
|
|
|
3226
|
59
|
|
|
|
|
|
nlen = A[0]; |
|
3227
|
|
|
|
|
|
|
/* if (nlen > 1000000000U) croak("overflow in frobenius number"); */ |
|
3228
|
59
|
50
|
|
|
|
|
New(0, N, nlen+1, UV); |
|
3229
|
59
|
|
|
|
|
|
N[0] = 0; |
|
3230
|
554304
|
100
|
|
|
|
|
for (j = 1; j < nlen; j++) |
|
3231
|
554245
|
|
|
|
|
|
N[j] = UV_MAX; |
|
3232
|
|
|
|
|
|
|
|
|
3233
|
427
|
100
|
|
|
|
|
for (i = 1; i < alen; i++) { |
|
3234
|
368
|
|
|
|
|
|
UV r, d, np, ai = A[i]; |
|
3235
|
368
|
|
|
|
|
|
np = N[ai % nlen]; |
|
3236
|
368
|
100
|
|
|
|
|
if (np != UV_MAX && np <= ai) continue; /* Redundant basis (opt 3) */ |
|
|
|
100
|
|
|
|
|
|
|
3237
|
304
|
|
|
|
|
|
d = gcd_ui(nlen, ai); |
|
3238
|
1504
|
100
|
|
|
|
|
for (r = 0; r < d; r++) { |
|
3239
|
1200
|
|
|
|
|
|
UV p, q, n = 0; |
|
3240
|
1200
|
100
|
|
|
|
|
if (r > 0) { |
|
3241
|
1064988
|
100
|
|
|
|
|
for (n = UV_MAX, q = r; q < nlen; q += d) |
|
3242
|
1064092
|
100
|
|
|
|
|
if (N[q] < n) |
|
3243
|
15454
|
|
|
|
|
|
n = N[q]; |
|
3244
|
|
|
|
|
|
|
} |
|
3245
|
1200
|
100
|
|
|
|
|
if (n != UV_MAX) { |
|
3246
|
3929660
|
100
|
|
|
|
|
for (j = 0; j < (nlen / d); j++) { |
|
3247
|
3928776
|
|
|
|
|
|
n += ai; |
|
3248
|
3928776
|
|
|
|
|
|
p = n % nlen; |
|
3249
|
3928776
|
100
|
|
|
|
|
if (N[p] >= n) N[p] = n; |
|
3250
|
1467472
|
|
|
|
|
|
else n = N[p]; |
|
3251
|
|
|
|
|
|
|
} |
|
3252
|
|
|
|
|
|
|
} |
|
3253
|
|
|
|
|
|
|
} |
|
3254
|
|
|
|
|
|
|
} |
|
3255
|
59
|
|
|
|
|
|
max = 0; |
|
3256
|
554363
|
100
|
|
|
|
|
for (i = 0; i < nlen; i++) |
|
3257
|
554304
|
50
|
|
|
|
|
if (N[i] == UV_MAX || (N[i] != UV_MAX && N[i] > max)) |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3258
|
33369
|
|
|
|
|
|
max = N[i]; |
|
3259
|
59
|
|
|
|
|
|
Safefree(N); |
|
3260
|
59
|
50
|
|
|
|
|
if (max == UV_MAX) return UV_MAX; |
|
3261
|
59
|
|
|
|
|
|
return max - nlen; |
|
3262
|
|
|
|
|
|
|
} |
|
3263
|
|
|
|
|
|
|
|
|
3264
|
|
|
|
|
|
|
|
|
3265
|
|
|
|
|
|
|
/* These rank/unrank are O(n^2) algorithms using O(n) in-place space. |
|
3266
|
|
|
|
|
|
|
* Bonet 2008 gives O(n log n) algorithms using a bit more space. |
|
3267
|
|
|
|
|
|
|
*/ |
|
3268
|
|
|
|
|
|
|
|
|
3269
|
5
|
|
|
|
|
|
bool num_to_perm(UV k, int n, int *vec) { |
|
3270
|
5
|
|
|
|
|
|
int i, j, t, si = 0; |
|
3271
|
5
|
|
|
|
|
|
UV f = factorial(n-1); |
|
3272
|
|
|
|
|
|
|
|
|
3273
|
8
|
100
|
|
|
|
|
while (f == 0) /* We can handle n! overflow if we have a valid k */ |
|
3274
|
3
|
|
|
|
|
|
f = factorial(n - 1 - ++si); |
|
3275
|
|
|
|
|
|
|
|
|
3276
|
5
|
100
|
|
|
|
|
if (k/f >= (UV)n) |
|
3277
|
1
|
|
|
|
|
|
k %= f*n; |
|
3278
|
|
|
|
|
|
|
|
|
3279
|
50
|
100
|
|
|
|
|
for (i = 0; i < n; i++) |
|
3280
|
45
|
|
|
|
|
|
vec[i] = i; |
|
3281
|
42
|
100
|
|
|
|
|
for (i = si; i < n-1; i++) { |
|
3282
|
37
|
|
|
|
|
|
UV p = k/f; |
|
3283
|
37
|
|
|
|
|
|
k -= p*f; |
|
3284
|
37
|
|
|
|
|
|
f /= n-i-1; |
|
3285
|
37
|
100
|
|
|
|
|
if (p > 0) { |
|
3286
|
66
|
100
|
|
|
|
|
for (j = i+p, t = vec[j]; j > i; j--) |
|
3287
|
47
|
|
|
|
|
|
vec[j] = vec[j-1]; |
|
3288
|
19
|
|
|
|
|
|
vec[i] = t; |
|
3289
|
|
|
|
|
|
|
} |
|
3290
|
|
|
|
|
|
|
} |
|
3291
|
5
|
|
|
|
|
|
return 1; |
|
3292
|
|
|
|
|
|
|
} |
|
3293
|
|
|
|
|
|
|
|
|
3294
|
5
|
|
|
|
|
|
bool perm_to_num(int n, int *vec, UV *rank) { |
|
3295
|
|
|
|
|
|
|
int i, j, k; |
|
3296
|
5
|
|
|
|
|
|
UV f, num = 0; |
|
3297
|
5
|
|
|
|
|
|
f = factorial(n-1); |
|
3298
|
5
|
100
|
|
|
|
|
if (f == 0) return 0; |
|
3299
|
42
|
100
|
|
|
|
|
for (i = 0; i < n-1; i++) { |
|
3300
|
340
|
100
|
|
|
|
|
for (j = i+1, k = 0; j < n; j++) |
|
3301
|
302
|
100
|
|
|
|
|
if (vec[j] < vec[i]) |
|
3302
|
137
|
|
|
|
|
|
k++; |
|
3303
|
38
|
50
|
|
|
|
|
if ((UV)k > (UV_MAX-num)/f) return 0; /* overflow */ |
|
3304
|
38
|
|
|
|
|
|
num += k*f; |
|
3305
|
38
|
|
|
|
|
|
f /= n-i-1; |
|
3306
|
|
|
|
|
|
|
} |
|
3307
|
4
|
|
|
|
|
|
*rank = num; |
|
3308
|
4
|
|
|
|
|
|
return 1; |
|
3309
|
|
|
|
|
|
|
} |
|
3310
|
|
|
|
|
|
|
|
|
3311
|
|
|
|
|
|
|
/* |
|
3312
|
|
|
|
|
|
|
* For k
|
|
3313
|
|
|
|
|
|
|
* https://www.math.upenn.edu/~wilf/website/CombinatorialAlgorithms.pdf |
|
3314
|
|
|
|
|
|
|
* Note it requires an O(k) complete shuffle as the results are sorted. |
|
3315
|
|
|
|
|
|
|
* |
|
3316
|
|
|
|
|
|
|
* This seems to be 4-100x faster than NumPy's random.{permutation,choice} |
|
3317
|
|
|
|
|
|
|
* for n under 100k or so. It's even faster with larger n. For example |
|
3318
|
|
|
|
|
|
|
* from numpy.random import choice; choice(100000000, 4, replace=False) |
|
3319
|
|
|
|
|
|
|
* uses 774MB and takes 55 seconds. We take less than 1 microsecond. |
|
3320
|
|
|
|
|
|
|
*/ |
|
3321
|
73
|
|
|
|
|
|
void randperm(void* ctx, UV n, UV k, UV *S) { |
|
3322
|
|
|
|
|
|
|
UV i, j; |
|
3323
|
|
|
|
|
|
|
|
|
3324
|
73
|
50
|
|
|
|
|
if (k > n) k = n; |
|
3325
|
|
|
|
|
|
|
|
|
3326
|
73
|
50
|
|
|
|
|
if (k == 0) { /* 0 of n */ |
|
3327
|
73
|
100
|
|
|
|
|
} else if (k == 1) { /* 1 of n. Pick one at random */ |
|
3328
|
9
|
|
|
|
|
|
S[0] = urandomm64(ctx,n); |
|
3329
|
64
|
100
|
|
|
|
|
} else if (k == 2 && n == 2) { /* 2 of 2. Flip a coin */ |
|
|
|
100
|
|
|
|
|
|
|
3330
|
4
|
|
|
|
|
|
S[0] = urandomb(ctx,1); |
|
3331
|
4
|
|
|
|
|
|
S[1] = 1-S[0]; |
|
3332
|
60
|
100
|
|
|
|
|
} else if (k == 2) { /* 2 of n. Pick 2 skipping dup */ |
|
3333
|
19
|
|
|
|
|
|
S[0] = urandomm64(ctx,n); |
|
3334
|
19
|
|
|
|
|
|
S[1] = urandomm64(ctx,n-1); |
|
3335
|
19
|
100
|
|
|
|
|
if (S[1] >= S[0]) S[1]++; |
|
3336
|
41
|
100
|
|
|
|
|
} else if (k < n/100 && k < 30) { /* k of n. Pick k with loop */ |
|
|
|
100
|
|
|
|
|
|
|
3337
|
22
|
100
|
|
|
|
|
for (i = 0; i < k; i++) { |
|
3338
|
|
|
|
|
|
|
do { |
|
3339
|
20
|
|
|
|
|
|
S[i] = urandomm64(ctx,n); |
|
3340
|
110
|
100
|
|
|
|
|
for (j = 0; j < i; j++) |
|
3341
|
90
|
50
|
|
|
|
|
if (S[j] == S[i]) |
|
3342
|
0
|
|
|
|
|
|
break; |
|
3343
|
20
|
50
|
|
|
|
|
} while (j < i); |
|
3344
|
|
|
|
|
|
|
} |
|
3345
|
39
|
100
|
|
|
|
|
} else if (k < n/100 && n > 1000000) {/* k of n. Pick k with dedup retry */ |
|
|
|
50
|
|
|
|
|
|
|
3346
|
4
|
100
|
|
|
|
|
for (j = 0; j < k; ) { |
|
3347
|
76
|
100
|
|
|
|
|
for (i = j; i < k; i++) /* Fill S[j .. k-1] then sort S */ |
|
3348
|
74
|
|
|
|
|
|
S[i] = urandomm64(ctx,n); |
|
3349
|
2
|
|
|
|
|
|
sort_uv_array(S, k); |
|
3350
|
74
|
100
|
|
|
|
|
for (j = 0, i = 1; i < k; i++) /* Find and remove dups. O(n). */ |
|
3351
|
72
|
50
|
|
|
|
|
if (S[j] != S[i]) |
|
3352
|
72
|
|
|
|
|
|
S[++j] = S[i]; |
|
3353
|
2
|
|
|
|
|
|
j++; |
|
3354
|
|
|
|
|
|
|
} |
|
3355
|
|
|
|
|
|
|
/* S is sorted unique k-selection of 0 to n-1. Shuffle. */ |
|
3356
|
76
|
100
|
|
|
|
|
for (i = 0; i < k; i++) { |
|
3357
|
74
|
|
|
|
|
|
j = urandomm64(ctx,k-i); |
|
3358
|
74
|
|
|
|
|
|
{ UV t = S[i]; S[i] = S[i+j]; S[i+j] = t; } |
|
3359
|
|
|
|
|
|
|
} |
|
3360
|
37
|
100
|
|
|
|
|
} else if (k < n/4) { /* k of n. Pick k with mask */ |
|
3361
|
17
|
|
|
|
|
|
uint32_t *mask, smask[8] = {0}; |
|
3362
|
17
|
50
|
|
|
|
|
if (n <= 32*8) mask = smask; |
|
3363
|
0
|
0
|
|
|
|
|
else Newz(0, mask, n/32 + ((n%32)?1:0), uint32_t); |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
3364
|
117
|
100
|
|
|
|
|
for (i = 0; i < k; i++) { |
|
3365
|
|
|
|
|
|
|
do { |
|
3366
|
100
|
|
|
|
|
|
j = urandomm64(ctx,n); |
|
3367
|
100
|
50
|
|
|
|
|
} while ( mask[j>>5] & (1U << (j&0x1F)) ); |
|
3368
|
100
|
|
|
|
|
|
S[i] = j; |
|
3369
|
100
|
|
|
|
|
|
mask[j>>5] |= (1U << (j&0x1F)); |
|
3370
|
|
|
|
|
|
|
} |
|
3371
|
17
|
50
|
|
|
|
|
if (mask != smask) Safefree(mask); |
|
3372
|
20
|
100
|
|
|
|
|
} else if (k < n) { /* k of n. FYK shuffle n, pick k */ |
|
3373
|
|
|
|
|
|
|
UV *T; |
|
3374
|
2
|
50
|
|
|
|
|
New(0, T, n, UV); |
|
3375
|
62
|
100
|
|
|
|
|
for (i = 0; i < n; i++) |
|
3376
|
60
|
|
|
|
|
|
T[i] = i; |
|
3377
|
26
|
100
|
|
|
|
|
for (i = 0; i < k && i <= n-2; i++) { |
|
|
|
50
|
|
|
|
|
|
|
3378
|
24
|
|
|
|
|
|
j = urandomm64(ctx,n-i); |
|
3379
|
24
|
|
|
|
|
|
S[i] = T[i+j]; |
|
3380
|
24
|
|
|
|
|
|
T[i+j] = T[i]; |
|
3381
|
|
|
|
|
|
|
} |
|
3382
|
2
|
|
|
|
|
|
Safefree(T); |
|
3383
|
|
|
|
|
|
|
} else { /* n of n. FYK shuffle. */ |
|
3384
|
334
|
100
|
|
|
|
|
for (i = 0; i < n; i++) |
|
3385
|
316
|
|
|
|
|
|
S[i] = i; |
|
3386
|
316
|
50
|
|
|
|
|
for (i = 0; i < k && i <= n-2; i++) { |
|
|
|
100
|
|
|
|
|
|
|
3387
|
298
|
|
|
|
|
|
j = urandomm64(ctx,n-i); |
|
3388
|
298
|
|
|
|
|
|
{ UV t = S[i]; S[i] = S[i+j]; S[i+j] = t; } |
|
3389
|
|
|
|
|
|
|
} |
|
3390
|
|
|
|
|
|
|
} |
|
3391
|
73
|
|
|
|
|
|
} |
|
3392
|
|
|
|
|
|
|
|
|
3393
|
|
|
|
|
|
|
#define SMOOTH_TEST(n,k,p,nextprime) \ |
|
3394
|
|
|
|
|
|
|
if (n < p*p) return (n <= k); /* p*p > n means n is prime */ \ |
|
3395
|
|
|
|
|
|
|
if ((n%p) == 0) { \ |
|
3396
|
|
|
|
|
|
|
do { n /= p; } while ((n%p) == 0); \ |
|
3397
|
|
|
|
|
|
|
if (n < nextprime) return 1; \ |
|
3398
|
|
|
|
|
|
|
} \ |
|
3399
|
|
|
|
|
|
|
if (k < nextprime) return (n <= k); |
|
3400
|
|
|
|
|
|
|
|
|
3401
|
590
|
|
|
|
|
|
bool is_smooth(UV n, UV k) { |
|
3402
|
|
|
|
|
|
|
UV fac[MPU_MAX_FACTORS+1]; |
|
3403
|
|
|
|
|
|
|
uint32_t i, p, pn, nfac; |
|
3404
|
|
|
|
|
|
|
|
|
3405
|
|
|
|
|
|
|
/* True if no prime factors of n are larger than k. */ |
|
3406
|
590
|
100
|
|
|
|
|
if (n <= 1) return 1; /* (0,k) = 1, (1,k) = 1 */ |
|
3407
|
534
|
100
|
|
|
|
|
if (k <= 1) return 0; /* (n,0) = (n,1) = 0 if n > 1 */ |
|
3408
|
458
|
100
|
|
|
|
|
if (n <= k) return 1; |
|
3409
|
|
|
|
|
|
|
/* k >= 2, n >= 2 */ |
|
3410
|
300
|
100
|
|
|
|
|
if (k == 2) return ((n & (n-1)) == 0); |
|
3411
|
356
|
100
|
|
|
|
|
while (n > 1 && !(n&1)) n >>= 1; |
|
|
|
100
|
|
|
|
|
|
|
3412
|
264
|
100
|
|
|
|
|
if (n <= k) return 1; |
|
3413
|
|
|
|
|
|
|
/* k >= 3, n >= 3 */ |
|
3414
|
|
|
|
|
|
|
|
|
3415
|
244
|
100
|
|
|
|
|
SMOOTH_TEST(n, k, 3, 5); /* after this, k >= 5, n > 3*3 */ |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3416
|
162
|
100
|
|
|
|
|
SMOOTH_TEST(n, k, 5, 7); /* after this, k >= 7, n > 5*5 */ |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3417
|
113
|
50
|
|
|
|
|
SMOOTH_TEST(n, k, 7, 11); /* after this, k >= 11, n > 7*7 */ |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3418
|
|
|
|
|
|
|
|
|
3419
|
|
|
|
|
|
|
/* Remove tiny factors. Tests to 499. */ |
|
3420
|
192
|
50
|
|
|
|
|
for (i = 5, pn = primes_tiny[i]; i < NPRIMES_TINY-1; i++) { |
|
3421
|
192
|
|
|
|
|
|
p = pn; pn = primes_tiny[i+1]; |
|
3422
|
237
|
100
|
|
|
|
|
SMOOTH_TEST(n, k, p, pn); |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3423
|
|
|
|
|
|
|
} |
|
3424
|
0
|
0
|
|
|
|
|
if (k < pn || n < pn*pn) return (n <= k); /* k >= 503 and n >= 503*503. */ |
|
|
|
0
|
|
|
|
|
|
|
3425
|
|
|
|
|
|
|
|
|
3426
|
0
|
0
|
|
|
|
|
if (is_prime(n)) return 0; |
|
3427
|
0
|
0
|
|
|
|
|
if (k <= 290000) { |
|
3428
|
0
|
|
|
|
|
|
nfac = trial_factor(n, fac, pn, k); |
|
3429
|
0
|
|
|
|
|
|
return (fac[nfac-1] <= k); |
|
3430
|
|
|
|
|
|
|
} |
|
3431
|
|
|
|
|
|
|
|
|
3432
|
0
|
|
|
|
|
|
nfac = trial_factor(n, fac, pn, 4999); |
|
3433
|
0
|
|
|
|
|
|
n = fac[nfac-1]; |
|
3434
|
0
|
|
|
|
|
|
pn = 5003; |
|
3435
|
0
|
0
|
|
|
|
|
if (k < pn || n < pn*pn) return (n <= k); /* k > 290k, n > 25M */ |
|
|
|
0
|
|
|
|
|
|
|
3436
|
|
|
|
|
|
|
|
|
3437
|
|
|
|
|
|
|
{ /* Complete factoring including primality test */ |
|
3438
|
0
|
|
|
|
|
|
factored_t nf = factorint(n); |
|
3439
|
0
|
|
|
|
|
|
return nf.f[nf.nfactors-1] <= k; |
|
3440
|
|
|
|
|
|
|
} |
|
3441
|
|
|
|
|
|
|
} |
|
3442
|
2203
|
|
|
|
|
|
bool is_rough(UV n, UV k) { |
|
3443
|
|
|
|
|
|
|
UV fac[MPU_MAX_FACTORS+1]; |
|
3444
|
|
|
|
|
|
|
int nfac; |
|
3445
|
|
|
|
|
|
|
|
|
3446
|
|
|
|
|
|
|
/* True if no prime factors of n are smaller than k. */ |
|
3447
|
|
|
|
|
|
|
|
|
3448
|
2203
|
100
|
|
|
|
|
if (n == 0) return (k == 0); |
|
3449
|
2175
|
100
|
|
|
|
|
if (n == 1) return 1; |
|
3450
|
|
|
|
|
|
|
/* n >= 2 */ |
|
3451
|
2147
|
100
|
|
|
|
|
if (k <= 1) return 1; |
|
3452
|
2071
|
100
|
|
|
|
|
if (k == 2) return (n >= 1); |
|
3453
|
2029
|
100
|
|
|
|
|
if (k == 3) return (n > 1 && (n&1)); |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3454
|
|
|
|
|
|
|
/* k >= 4 */ |
|
3455
|
|
|
|
|
|
|
|
|
3456
|
1984
|
100
|
|
|
|
|
if (!(n&1)) return 0; |
|
3457
|
1064
|
100
|
|
|
|
|
if (!(n%3)) return 0; |
|
3458
|
756
|
100
|
|
|
|
|
if (k <= 5) return 1; |
|
3459
|
677
|
100
|
|
|
|
|
if (!(n%5)) return 0; |
|
3460
|
|
|
|
|
|
|
|
|
3461
|
565
|
100
|
|
|
|
|
if (k <= 2500) { |
|
3462
|
560
|
|
|
|
|
|
nfac = trial_factor(n, fac, 7, k); |
|
3463
|
560
|
|
|
|
|
|
return (fac[0] >= k); |
|
3464
|
|
|
|
|
|
|
} |
|
3465
|
|
|
|
|
|
|
|
|
3466
|
|
|
|
|
|
|
/* TODO: look into factor_one. */ |
|
3467
|
|
|
|
|
|
|
/* But it doesn't guarantee returning a prime factor or the smallest. */ |
|
3468
|
|
|
|
|
|
|
|
|
3469
|
5
|
|
|
|
|
|
nfac = trial_factor(n, fac, 7, 200); |
|
3470
|
5
|
100
|
|
|
|
|
if (nfac > 1 && fac[nfac-2] <= k) return 0; |
|
|
|
50
|
|
|
|
|
|
|
3471
|
4
|
|
|
|
|
|
n = fac[nfac-1]; |
|
3472
|
4
|
50
|
|
|
|
|
if (n < k) return 0; |
|
3473
|
|
|
|
|
|
|
|
|
3474
|
4
|
100
|
|
|
|
|
if ( (n >> 30) >= 64) { /* Arbitrarily chose 2^36 for more tests */ |
|
3475
|
3
|
100
|
|
|
|
|
if (is_prime(n)) return 1; |
|
3476
|
2
|
|
|
|
|
|
nfac = pminus1_factor(n, fac, 500, 500); |
|
3477
|
2
|
100
|
|
|
|
|
if (nfac > 1) { /* 2 factors, but they could be composites */ |
|
3478
|
1
|
50
|
|
|
|
|
if (fac[0] < k || fac[1] < k) return 0; |
|
|
|
0
|
|
|
|
|
|
|
3479
|
0
|
0
|
|
|
|
|
if (factorint(fac[0]).f[0] < k) return 0; |
|
3480
|
0
|
0
|
|
|
|
|
if (factorint(fac[1]).f[0] < k) return 0; |
|
3481
|
0
|
|
|
|
|
|
return 1; |
|
3482
|
|
|
|
|
|
|
} |
|
3483
|
|
|
|
|
|
|
} |
|
3484
|
|
|
|
|
|
|
|
|
3485
|
|
|
|
|
|
|
/* Complete factoring including primality test */ |
|
3486
|
2
|
|
|
|
|
|
return factorint(n).f[0] >= k; |
|
3487
|
|
|
|
|
|
|
} |
|
3488
|
|
|
|
|
|
|
|
|
3489
|
|
|
|
|
|
|
|
|
3490
|
146
|
|
|
|
|
|
static UV _divsum1(UV prod, UV f, uint32_t e) { |
|
3491
|
|
|
|
|
|
|
UV pke, fmult; |
|
3492
|
245
|
100
|
|
|
|
|
for (pke = f, fmult = 1+f; e > 1; e--) { |
|
3493
|
99
|
|
|
|
|
|
pke *= f; |
|
3494
|
99
|
|
|
|
|
|
fmult += pke; |
|
3495
|
|
|
|
|
|
|
} |
|
3496
|
146
|
|
|
|
|
|
return prod * fmult; |
|
3497
|
|
|
|
|
|
|
} |
|
3498
|
|
|
|
|
|
|
|
|
3499
|
297
|
|
|
|
|
|
bool is_practical(UV n) { |
|
3500
|
|
|
|
|
|
|
factored_t nf; |
|
3501
|
|
|
|
|
|
|
UV prod; |
|
3502
|
|
|
|
|
|
|
uint32_t i; |
|
3503
|
|
|
|
|
|
|
|
|
3504
|
297
|
100
|
|
|
|
|
if (n == 0 || (n & 1)) return (n == 1); |
|
|
|
100
|
|
|
|
|
|
|
3505
|
158
|
100
|
|
|
|
|
if ((n & (n-1)) == 0) return 1; /* All powers of 2 are practical */ |
|
3506
|
|
|
|
|
|
|
/* Allowable prefixes: {6,4} => {6,20,28,8} => {6,20,28,88,104,16} */ |
|
3507
|
151
|
100
|
|
|
|
|
if ((n % 6) && (n % 20) && (n % 28) && (n % 88) && (n % 104) && (n % 16)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
3508
|
91
|
|
|
|
|
|
return 0; |
|
3509
|
|
|
|
|
|
|
|
|
3510
|
|
|
|
|
|
|
/* In theory for better performance we should test with small primes |
|
3511
|
|
|
|
|
|
|
* before fully factoring. On average it doesn't seem to help. */ |
|
3512
|
60
|
|
|
|
|
|
nf = factorint(n); |
|
3513
|
60
|
50
|
|
|
|
|
MPUassert(nf.f[0] == 2, "is_practical first factor must be 2"); |
|
3514
|
60
|
|
|
|
|
|
prod = _divsum1(1, 2, nf.e[0]); |
|
3515
|
146
|
100
|
|
|
|
|
for (i = 1; i < nf.nfactors; i++) { |
|
3516
|
93
|
100
|
|
|
|
|
if (nf.f[i] > (1 + prod)) |
|
3517
|
7
|
|
|
|
|
|
return 0; |
|
3518
|
86
|
|
|
|
|
|
prod = _divsum1(prod, nf.f[i], nf.e[i]); |
|
3519
|
|
|
|
|
|
|
} |
|
3520
|
53
|
|
|
|
|
|
return 1; |
|
3521
|
|
|
|
|
|
|
} |
|
3522
|
|
|
|
|
|
|
|
|
3523
|
1066091
|
|
|
|
|
|
int is_delicate_prime(UV n, uint32_t b) { |
|
3524
|
|
|
|
|
|
|
|
|
3525
|
1066091
|
50
|
|
|
|
|
if (b < 2) croak("is_delicate_prime base must be >= 2"); |
|
3526
|
1066091
|
100
|
|
|
|
|
if (b == 10 && n < 100) return 0; /* All 1,2,3,4 digit inputs are false */ |
|
|
|
100
|
|
|
|
|
|
|
3527
|
1065991
|
100
|
|
|
|
|
if (b == 3 && n == 2) return 1; |
|
|
|
100
|
|
|
|
|
|
|
3528
|
|
|
|
|
|
|
|
|
3529
|
1065989
|
100
|
|
|
|
|
if (!is_prime(n)) return 0; |
|
3530
|
|
|
|
|
|
|
|
|
3531
|
84417
|
100
|
|
|
|
|
if (b == 10) { |
|
3532
|
|
|
|
|
|
|
|
|
3533
|
83009
|
|
|
|
|
|
UV d, dold, dnew, digpow, maxd = (BITS_PER_WORD == 32) ? 9 : 19; |
|
3534
|
|
|
|
|
|
|
|
|
3535
|
83009
|
50
|
|
|
|
|
if (n >= ipow(10,maxd)) return -1; /* We can't check all values */ |
|
3536
|
|
|
|
|
|
|
|
|
3537
|
|
|
|
|
|
|
/* Check the last digit, given a > 1 digit prime, must be one of these. */ |
|
3538
|
83009
|
|
|
|
|
|
dold = n % 10; |
|
3539
|
83009
|
100
|
|
|
|
|
if ( (dold != 1 && is_prime(n - dold + 1)) || |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3540
|
71537
|
100
|
|
|
|
|
(dold != 3 && is_prime(n - dold + 3)) || |
|
|
|
100
|
|
|
|
|
|
|
3541
|
61546
|
100
|
|
|
|
|
(dold != 7 && is_prime(n - dold + 7)) || |
|
|
|
100
|
|
|
|
|
|
|
3542
|
41530
|
100
|
|
|
|
|
(dold != 9 && is_prime(n - dold + 9)) ) |
|
3543
|
37743
|
|
|
|
|
|
return 0; |
|
3544
|
|
|
|
|
|
|
|
|
3545
|
|
|
|
|
|
|
/* Check the rest of the digits. */ |
|
3546
|
52855
|
50
|
|
|
|
|
for (d = 1, digpow = 10; d <= maxd && n >= digpow; digpow *= 10, d++) { |
|
|
|
100
|
|
|
|
|
|
|
3547
|
52822
|
|
|
|
|
|
dold = (n / digpow) % 10; |
|
3548
|
268897
|
100
|
|
|
|
|
for (dnew = 0; dnew < 10; dnew++) |
|
3549
|
261308
|
100
|
|
|
|
|
if (dnew != dold && is_prime(n - dold*digpow + dnew*digpow)) |
|
|
|
100
|
|
|
|
|
|
|
3550
|
45233
|
|
|
|
|
|
return 0; |
|
3551
|
|
|
|
|
|
|
} |
|
3552
|
|
|
|
|
|
|
|
|
3553
|
1408
|
100
|
|
|
|
|
} else if (b == 2) { |
|
3554
|
|
|
|
|
|
|
|
|
3555
|
|
|
|
|
|
|
UV bit; |
|
3556
|
60
|
100
|
|
|
|
|
if (n < 127) return 0; |
|
3557
|
130
|
50
|
|
|
|
|
for (bit = log2floor(n); bit > 0; bit--) |
|
|
|
100
|
|
|
|
|
|
|
3558
|
120
|
100
|
|
|
|
|
if (is_prime(n ^ (UVCONST(1) << bit))) |
|
3559
|
20
|
|
|
|
|
|
return 0; |
|
3560
|
|
|
|
|
|
|
|
|
3561
|
|
|
|
|
|
|
} else { |
|
3562
|
|
|
|
|
|
|
|
|
3563
|
|
|
|
|
|
|
#if 0 /* Our simpler method, but must add proper overflow check. */ |
|
3564
|
|
|
|
|
|
|
UV dold, dnew, digpow, N; |
|
3565
|
|
|
|
|
|
|
for (digpow = 1; n >= digpow; digpow *= b) { |
|
3566
|
|
|
|
|
|
|
dold = (n / digpow) % b; |
|
3567
|
|
|
|
|
|
|
if ( (UV_MAX-(b-1)*digpow) < (n-dold*digpow) ) return -1; |
|
3568
|
|
|
|
|
|
|
for (dnew = 0, N = n-dold*digpow; dnew < b; dnew++, N += digpow) |
|
3569
|
|
|
|
|
|
|
if (dnew != dold && is_prime(N)) |
|
3570
|
|
|
|
|
|
|
return 0; |
|
3571
|
|
|
|
|
|
|
} |
|
3572
|
|
|
|
|
|
|
#endif |
|
3573
|
|
|
|
|
|
|
|
|
3574
|
|
|
|
|
|
|
/* Algorithm isWeakly from Emily Stamm, 2020. */ |
|
3575
|
|
|
|
|
|
|
UV current, bm; |
|
3576
|
2406
|
100
|
|
|
|
|
for (bm = 1; n >= bm; bm *= b) { |
|
3577
|
|
|
|
|
|
|
uint32_t j, counter; |
|
3578
|
2346
|
|
|
|
|
|
UV bmb = bm * b; |
|
3579
|
2346
|
50
|
|
|
|
|
if ( ((UV_MAX/b) < bm) || ((UV_MAX-bmb) < n) ) return -1; /* overflow */ |
|
|
|
50
|
|
|
|
|
|
|
3580
|
|
|
|
|
|
|
/* Check all n + j * b^m are composite */ |
|
3581
|
2346
|
|
|
|
|
|
for (counter = 0, current = n+bm; |
|
3582
|
9358
|
100
|
|
|
|
|
(n % bm) != (current % bmb); |
|
3583
|
7012
|
|
|
|
|
|
counter++, current += bm) { |
|
3584
|
7705
|
50
|
|
|
|
|
if (counter >= b-1) croak("is_delicate_prime overflow failure\n"); |
|
3585
|
7705
|
100
|
|
|
|
|
if (is_prime(current)) |
|
3586
|
693
|
|
|
|
|
|
return 0; |
|
3587
|
|
|
|
|
|
|
} |
|
3588
|
|
|
|
|
|
|
/* Check all n - j * b^m are composite */ |
|
3589
|
8012
|
100
|
|
|
|
|
for (j = 1, current = n-bm; j < b-counter; j++, current -= bm) { |
|
3590
|
6954
|
100
|
|
|
|
|
if (is_prime(current)) |
|
3591
|
595
|
|
|
|
|
|
return 0; |
|
3592
|
|
|
|
|
|
|
} |
|
3593
|
|
|
|
|
|
|
} |
|
3594
|
|
|
|
|
|
|
|
|
3595
|
|
|
|
|
|
|
} |
|
3596
|
103
|
|
|
|
|
|
return 1; |
|
3597
|
|
|
|
|
|
|
} |
|
3598
|
|
|
|
|
|
|
|
|
3599
|
|
|
|
|
|
|
|
|
3600
|
116
|
|
|
|
|
|
bool is_sum_of_two_squares(UV n) { |
|
3601
|
|
|
|
|
|
|
factored_t nf; |
|
3602
|
|
|
|
|
|
|
uint32_t i; |
|
3603
|
|
|
|
|
|
|
|
|
3604
|
116
|
100
|
|
|
|
|
if (n < 3) return 1; |
|
3605
|
|
|
|
|
|
|
|
|
3606
|
214
|
100
|
|
|
|
|
while (!(n&1)) n >>= 1; /* Remove all factors of two */ |
|
3607
|
|
|
|
|
|
|
|
|
3608
|
111
|
100
|
|
|
|
|
if ((n % 4) == 3) return 0; |
|
3609
|
|
|
|
|
|
|
|
|
3610
|
|
|
|
|
|
|
/* if (is_prime(n)) return ((n % 4) == 1); */ |
|
3611
|
|
|
|
|
|
|
|
|
3612
|
|
|
|
|
|
|
/* TODO: a factor iterator should handle this reasonably */ |
|
3613
|
86
|
100
|
|
|
|
|
for (i = 0; !(n % 3); n /= 3) { i++; } if ((i & 1) == 1) return 0; |
|
|
|
100
|
|
|
|
|
|
|
3614
|
57
|
100
|
|
|
|
|
for (i = 0; !(n % 7); n /= 7) { i++; } if ((i & 1) == 1) return 0; |
|
|
|
100
|
|
|
|
|
|
|
3615
|
52
|
100
|
|
|
|
|
for (i = 0; !(n % 11); n /= 11) { i++; } if ((i & 1) == 1) return 0; |
|
|
|
100
|
|
|
|
|
|
|
3616
|
51
|
100
|
|
|
|
|
for (i = 0; !(n % 19); n /= 19) { i++; } if ((i & 1) == 1) return 0; |
|
|
|
100
|
|
|
|
|
|
|
3617
|
50
|
100
|
|
|
|
|
for (i = 0; !(n % 23); n /= 23) { i++; } if ((i & 1) == 1) return 0; |
|
|
|
100
|
|
|
|
|
|
|
3618
|
49
|
100
|
|
|
|
|
for (i = 0; !(n % 31); n /= 31) { i++; } if ((i & 1) == 1) return 0; |
|
|
|
100
|
|
|
|
|
|
|
3619
|
|
|
|
|
|
|
|
|
3620
|
47
|
|
|
|
|
|
nf = factorint(n); |
|
3621
|
80
|
100
|
|
|
|
|
for (i = 0; i < nf.nfactors; i++) |
|
3622
|
34
|
100
|
|
|
|
|
if ( (nf.f[i] % 4) == 3 && (nf.e[i] & 1) == 1 ) |
|
|
|
50
|
|
|
|
|
|
|
3623
|
1
|
|
|
|
|
|
return 0; |
|
3624
|
|
|
|
|
|
|
|
|
3625
|
46
|
|
|
|
|
|
return 1; |
|
3626
|
|
|
|
|
|
|
} |
|
3627
|
|
|
|
|
|
|
|
|
3628
|
119
|
|
|
|
|
|
bool is_sum_of_three_squares(UV n) { |
|
3629
|
119
|
|
|
|
|
|
UV tz = valuation(n,2); |
|
3630
|
119
|
100
|
|
|
|
|
return ((tz & 1) == 1) || (((n>>tz) % 8) != 7); |
|
|
|
100
|
|
|
|
|
|
|
3631
|
|
|
|
|
|
|
} |
|
3632
|
|
|
|
|
|
|
|
|
3633
|
|
|
|
|
|
|
#if 0 /* https://eprint.iacr.org/2023/807.pdf */ |
|
3634
|
|
|
|
|
|
|
static UV halfgcd(UV m, UV u) { |
|
3635
|
|
|
|
|
|
|
UV l = isqrt(m); |
|
3636
|
|
|
|
|
|
|
UV a = m, b = u; |
|
3637
|
|
|
|
|
|
|
while (a > l) { |
|
3638
|
|
|
|
|
|
|
UV r = a % b; |
|
3639
|
|
|
|
|
|
|
a = b; |
|
3640
|
|
|
|
|
|
|
b = r; |
|
3641
|
|
|
|
|
|
|
} |
|
3642
|
|
|
|
|
|
|
return a; |
|
3643
|
|
|
|
|
|
|
} |
|
3644
|
|
|
|
|
|
|
|
|
3645
|
|
|
|
|
|
|
/* Given an initial root, solve */ |
|
3646
|
|
|
|
|
|
|
static bool corn_one(UV *x, UV *y, UV u, UV d, UV p) { |
|
3647
|
|
|
|
|
|
|
UV rk = halfgcd(p, u); |
|
3648
|
|
|
|
|
|
|
u = negmod(sqrmod(rk,p),p); |
|
3649
|
|
|
|
|
|
|
u = (u % d == 0) ? u/d : 0; |
|
3650
|
|
|
|
|
|
|
if (u && is_perfect_square(u)) { |
|
3651
|
|
|
|
|
|
|
*x = rk; |
|
3652
|
|
|
|
|
|
|
*y = isqrt(u); |
|
3653
|
|
|
|
|
|
|
return 1; |
|
3654
|
|
|
|
|
|
|
} |
|
3655
|
|
|
|
|
|
|
return 0; |
|
3656
|
|
|
|
|
|
|
} |
|
3657
|
|
|
|
|
|
|
#else |
|
3658
|
|
|
|
|
|
|
/* Given an initial root, solve. Algorithm 2.3.12 of C&P */ |
|
3659
|
5
|
|
|
|
|
|
static bool corn_one(UV *x, UV *y, UV u, UV d, UV p) { |
|
3660
|
5
|
|
|
|
|
|
UV a = p; |
|
3661
|
5
|
|
|
|
|
|
UV b = (u >= p-u) ? u : p-u; /* Select larger root */ |
|
3662
|
5
|
|
|
|
|
|
uint32_t c = isqrt(p); |
|
3663
|
25
|
100
|
|
|
|
|
while (b > c) { UV t = a % b; a = b; b = t; } |
|
3664
|
5
|
|
|
|
|
|
u = p - b*b; |
|
3665
|
5
|
50
|
|
|
|
|
u = (u % d == 0) ? u/d : 0; |
|
3666
|
5
|
50
|
|
|
|
|
if (u && is_perfect_square_ret(u,&c)) { |
|
|
|
50
|
|
|
|
|
|
|
3667
|
5
|
|
|
|
|
|
*x = b; |
|
3668
|
5
|
|
|
|
|
|
*y = c; |
|
3669
|
5
|
|
|
|
|
|
return 1; |
|
3670
|
|
|
|
|
|
|
} |
|
3671
|
0
|
|
|
|
|
|
return 0; |
|
3672
|
|
|
|
|
|
|
} |
|
3673
|
|
|
|
|
|
|
#endif |
|
3674
|
|
|
|
|
|
|
|
|
3675
|
|
|
|
|
|
|
/* Cornacchia-Smith run over each root. */ |
|
3676
|
0
|
|
|
|
|
|
static bool corn_all(UV *x, UV *y, UV d, UV p) { |
|
3677
|
0
|
|
|
|
|
|
UV negd = negmod(d,p), i, nroots, *roots; |
|
3678
|
0
|
|
|
|
|
|
bool success = 0; |
|
3679
|
0
|
|
|
|
|
|
roots = allsqrtmod(&nroots, negd, p); |
|
3680
|
0
|
0
|
|
|
|
|
if (roots) { |
|
3681
|
0
|
0
|
|
|
|
|
for (i = 0; i < nroots/2 && !success; i++) |
|
|
|
0
|
|
|
|
|
|
|
3682
|
0
|
|
|
|
|
|
success = corn_one(x, y, roots[i], d, p); |
|
3683
|
0
|
|
|
|
|
|
Safefree(roots); |
|
3684
|
|
|
|
|
|
|
} |
|
3685
|
0
|
|
|
|
|
|
return success; |
|
3686
|
|
|
|
|
|
|
} |
|
3687
|
|
|
|
|
|
|
|
|
3688
|
18
|
|
|
|
|
|
bool cornacchia(UV *x, UV *y, UV d, UV p) { |
|
3689
|
|
|
|
|
|
|
UV u, negd, limu; |
|
3690
|
|
|
|
|
|
|
uint32_t root; |
|
3691
|
|
|
|
|
|
|
|
|
3692
|
18
|
100
|
|
|
|
|
if (p == 0) { |
|
3693
|
1
|
|
|
|
|
|
*x = *y = 0; |
|
3694
|
1
|
|
|
|
|
|
return 1; |
|
3695
|
|
|
|
|
|
|
} |
|
3696
|
|
|
|
|
|
|
|
|
3697
|
17
|
100
|
|
|
|
|
if (d == 0) { |
|
3698
|
2
|
100
|
|
|
|
|
if (!is_perfect_square_ret(p,&root)) return 0; |
|
3699
|
1
|
|
|
|
|
|
*x = root; *y = 0; |
|
3700
|
1
|
|
|
|
|
|
return 1; |
|
3701
|
|
|
|
|
|
|
} |
|
3702
|
|
|
|
|
|
|
|
|
3703
|
15
|
|
|
|
|
|
negd = negmod(d, p); |
|
3704
|
|
|
|
|
|
|
|
|
3705
|
15
|
100
|
|
|
|
|
if (is_prime(p)) { |
|
3706
|
5
|
50
|
|
|
|
|
if (kronecker_uu(negd,p) == -1) return 0; |
|
3707
|
5
|
50
|
|
|
|
|
if (!sqrtmodp(&u, negd, p)) return 0; |
|
3708
|
5
|
|
|
|
|
|
return corn_one(x, y, u, d, p); |
|
3709
|
|
|
|
|
|
|
} |
|
3710
|
|
|
|
|
|
|
|
|
3711
|
10
|
50
|
|
|
|
|
if (((p >> 31) >> 22) && kronecker_uu(negd,p) != -1 && corn_all(x, y, d, p)) |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
3712
|
0
|
|
|
|
|
|
return 1; |
|
3713
|
|
|
|
|
|
|
|
|
3714
|
|
|
|
|
|
|
/* Loop through all valid integers until one is found. |
|
3715
|
|
|
|
|
|
|
* Until p is quite large, this is faster than using allsqrtmod. |
|
3716
|
|
|
|
|
|
|
* It also finds many solutions for composites. |
|
3717
|
|
|
|
|
|
|
*/ |
|
3718
|
166
|
50
|
|
|
|
|
for (u = 0, limu = isqrt(p/d); u <= limu; u++) { |
|
3719
|
166
|
|
|
|
|
|
UV t = p - d*u*u; |
|
3720
|
166
|
100
|
|
|
|
|
if (is_perfect_square_ret(t,&root)) { |
|
3721
|
10
|
|
|
|
|
|
*x = root; *y = u; return 1; |
|
3722
|
|
|
|
|
|
|
} |
|
3723
|
|
|
|
|
|
|
} |
|
3724
|
|
|
|
|
|
|
|
|
3725
|
0
|
|
|
|
|
|
return 0; |
|
3726
|
|
|
|
|
|
|
} |
|
3727
|
|
|
|
|
|
|
|
|
3728
|
|
|
|
|
|
|
|
|
3729
|
|
|
|
|
|
|
|
|
3730
|
|
|
|
|
|
|
|
|
3731
|
|
|
|
|
|
|
/* TODO: */ |
|
3732
|
|
|
|
|
|
|
/* See https://arxiv.org/pdf/2208.01725.pdf for new info on smooth count |
|
3733
|
|
|
|
|
|
|
* estimate methods. Consider adding an estimate function. */ |
|
3734
|
|
|
|
|
|
|
|
|
3735
|
|
|
|
|
|
|
static const unsigned char _psi_cache_v__7[128] = {8,9,10,10,11,11,12,13,14,14,15,15,16,17,17,17,18,19,19,20,21,21,22,22,23,23,23,24,25,25,25,25,26,26,27,27,27,28,28,28,29,30,31,31,31,31,32,32,33,33,33,33,34,34,34,35,36,36,36,36,36,36,37,37,38,38,38,39,39,39,39,39,40,41,41,41,42,42,42,42,42,42,43,43,43,43,43,43,44,44,45,45,46,46,46,46,46,47,47,47,48,48,48,48,49,49,49,49,49,49,49,49,50,50,50,50,50,51,52,52,53,53,53,53,53,53,53,54}; |
|
3736
|
|
|
|
|
|
|
static const unsigned char _psi_cache_v_11[96] = {12,12,13,14,15,15,16,16,17,18,19,19,20,21,21,22,23,23,24,24,25,26,26,27,28,28,28,28,29,29,30,30,31,32,32,32,33,34,35,35,35,35,36,37,38,38,38,38,39,39,39,40,41,41,42,42,42,42,43,43,44,44,44,45,45,46,46,46,47,48,48,48,49,49,49,49,50,50,51,51,51,51,51,51,52,52,53,54,55,55,55,55,55,56,56,56}; |
|
3737
|
|
|
|
|
|
|
static const unsigned char _psi_cache_v_13[64] = {14,15,16,16,17,17,18,19,20,20,21,22,23,24,25,25,26,26,27,28,28,29,30,30,30,31,32,32,33,33,34,35,35,35,36,37,38,38,39,39,40,41,42,42,42,42,43,43,43,44,45,46,47,47,47,47,48,48,49,49,49,50,50,51}; |
|
3738
|
|
|
|
|
|
|
|
|
3739
|
23492
|
|
|
|
|
|
UV debruijn_psi(UV x, UV y) { |
|
3740
|
|
|
|
|
|
|
UV sum, x3, x5; |
|
3741
|
23492
|
100
|
|
|
|
|
if (x < 1) return 0; |
|
3742
|
23486
|
100
|
|
|
|
|
if (y <= 1) return 1; |
|
3743
|
23476
|
100
|
|
|
|
|
if (y >= x) return x; |
|
3744
|
19259
|
100
|
|
|
|
|
if (y == 2) return 1 + log2floor(x); |
|
|
|
50
|
|
|
|
|
|
|
3745
|
19256
|
100
|
|
|
|
|
if (!(y&1)) y--; /* Make y odd for simplicity */ |
|
3746
|
|
|
|
|
|
|
|
|
3747
|
|
|
|
|
|
|
/* Caches etc. to avoid recursion - about 1.6x speedup for big inputs */ |
|
3748
|
19256
|
100
|
|
|
|
|
if (y == 7 && x- 7 <=128) return _psi_cache_v__7[x-1- 7]; |
|
|
|
100
|
|
|
|
|
|
|
3749
|
14948
|
100
|
|
|
|
|
if (y == 11 && x-11 <= 96) return _psi_cache_v_11[x-1-11]; |
|
|
|
100
|
|
|
|
|
|
|
3750
|
11901
|
100
|
|
|
|
|
if (y == 13 && x-13 <= 64) return _psi_cache_v_13[x-1-13]; |
|
|
|
100
|
|
|
|
|
|
|
3751
|
9957
|
100
|
|
|
|
|
if (y >= 17 && x <= 128) { |
|
|
|
100
|
|
|
|
|
|
|
3752
|
|
|
|
|
|
|
/* mpu 'for (7..128) { $f=(factor($_))[-1]; push(@$X,$_),push(@$Y,$f) if $f > 17; } say scalar(@$X); say join(",",@$_) for ($X,$Y);' */ |
|
3753
|
|
|
|
|
|
|
static const unsigned char xt[48] = {19,23,29,31,37,38,41,43,46,47,53,57,58,59,61,62,67,69,71,73,74,76,79,82,83,86,87,89,92,93,94,95,97,101,103,106,107,109,111,113,114,115,116,118,122,123,124,127}; |
|
3754
|
|
|
|
|
|
|
static const unsigned char yt[48] = {19,23,29,31,37,19,41,43,23,47,53,19,29,59,61,31,67,23,71,73,37,19,79,41,83,43,29,89,23,31,47,19,97,101,103,53,107,109,37,113,19,23,29,59,61,41,31,127}; |
|
3755
|
|
|
|
|
|
|
unsigned char i; |
|
3756
|
54652
|
100
|
|
|
|
|
for (i = 0, sum = x; i < 48 && x >= xt[i]; i++) |
|
|
|
100
|
|
|
|
|
|
|
3757
|
50235
|
100
|
|
|
|
|
if (y < yt[i]) |
|
3758
|
36256
|
|
|
|
|
|
sum--; |
|
3759
|
4417
|
|
|
|
|
|
return sum; |
|
3760
|
|
|
|
|
|
|
} |
|
3761
|
|
|
|
|
|
|
|
|
3762
|
|
|
|
|
|
|
/* given z < y < x, (e.g. z=2 or z=19) |
|
3763
|
|
|
|
|
|
|
* psi(x,y) = psi(x,z) + sum[z+1..y] psi(x/p,p) */ |
|
3764
|
|
|
|
|
|
|
|
|
3765
|
5540
|
50
|
|
|
|
|
sum = 1 + log2floor(x); /* debruijn_psi(x,2) */ |
|
3766
|
|
|
|
|
|
|
/* if (y >= 3) sum += debruijn_psi(x/3, 3); */ |
|
3767
|
|
|
|
|
|
|
/* if (y >= 5) sum += debruijn_psi(x/5, 5); */ |
|
3768
|
5540
|
50
|
|
|
|
|
if (y >= 3) { |
|
3769
|
26895
|
100
|
|
|
|
|
for (x3 = x/3; x3 > 3; x3 /= 3) |
|
3770
|
21355
|
50
|
|
|
|
|
sum += 1+log2floor(x3); |
|
3771
|
5540
|
|
|
|
|
|
sum += x3; |
|
3772
|
|
|
|
|
|
|
} |
|
3773
|
5540
|
100
|
|
|
|
|
if (y >= 5) { |
|
3774
|
17930
|
100
|
|
|
|
|
for (x5 = x/5; x5 > 5; x5 /= 5) { |
|
3775
|
12393
|
50
|
|
|
|
|
sum += 1+log2floor(x5); |
|
3776
|
32970
|
100
|
|
|
|
|
for (x3 = x5/3; x3 > 3; x3 /= 3) |
|
3777
|
20577
|
50
|
|
|
|
|
sum += 1+log2floor(x3); |
|
3778
|
12393
|
|
|
|
|
|
sum += x3; |
|
3779
|
|
|
|
|
|
|
} |
|
3780
|
5537
|
|
|
|
|
|
sum += x5; |
|
3781
|
|
|
|
|
|
|
} |
|
3782
|
5540
|
100
|
|
|
|
|
if (y >= 7) sum += debruijn_psi(x/ 7, 7); |
|
3783
|
5540
|
100
|
|
|
|
|
if (y >= 11) sum += debruijn_psi(x/11,11); |
|
3784
|
5540
|
100
|
|
|
|
|
if (y >= 13) sum += debruijn_psi(x/13,13); |
|
3785
|
5540
|
100
|
|
|
|
|
if (y >= 17) sum += debruijn_psi(x/17,17); |
|
3786
|
5540
|
100
|
|
|
|
|
if (y >= 19) sum += debruijn_psi(x/19,19); |
|
3787
|
5540
|
100
|
|
|
|
|
if (y >= 23) sum += debruijn_psi(x/23,23); |
|
3788
|
5540
|
100
|
|
|
|
|
if (y >= 29) { |
|
3789
|
31379
|
50
|
|
|
|
|
START_DO_FOR_EACH_PRIME(29, y) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
3790
|
29470
|
|
|
|
|
|
UV xp = x/p; |
|
3791
|
29470
|
100
|
|
|
|
|
sum += (p >= xp) ? xp : debruijn_psi(xp, p); |
|
3792
|
|
|
|
|
|
|
} END_DO_FOR_EACH_PRIME |
|
3793
|
|
|
|
|
|
|
} |
|
3794
|
|
|
|
|
|
|
|
|
3795
|
5540
|
|
|
|
|
|
return sum; |
|
3796
|
|
|
|
|
|
|
} |
|
3797
|
|
|
|
|
|
|
|
|
3798
|
37
|
|
|
|
|
|
UV buchstab_phi(UV x, UV y) { |
|
3799
|
37
|
100
|
|
|
|
|
if (y <= 2) return x; |
|
3800
|
19
|
100
|
|
|
|
|
if (y <= 3) return x - x/2; |
|
3801
|
13
|
100
|
|
|
|
|
if (y <= 5) return x - x/2 - x/3 + x/6; |
|
3802
|
|
|
|
|
|
|
/* We'll use the legendre_phi function we already have. */ |
|
3803
|
1
|
|
|
|
|
|
return legendre_phi(x, prime_count(y-1)); |
|
3804
|
|
|
|
|
|
|
} |
|
3805
|
|
|
|
|
|
|
|
|
3806
|
|
|
|
|
|
|
|
|
3807
|
1
|
|
|
|
|
|
UV random_factored_integer(void* ctx, UV n, int *nf, UV *factors) { |
|
3808
|
|
|
|
|
|
|
UV r, s, nfac; |
|
3809
|
1
|
50
|
|
|
|
|
if (n < 1) |
|
3810
|
0
|
|
|
|
|
|
return 0; |
|
3811
|
|
|
|
|
|
|
#if BITS_PER_WORD == 64 && (USE_MONTMATH || MULMODS_ARE_FAST) |
|
3812
|
|
|
|
|
|
|
if (1) /* Our factoring is very fast, just use it */ |
|
3813
|
|
|
|
|
|
|
#elif BITS_PER_WORD == 64 |
|
3814
|
|
|
|
|
|
|
if (n < UVCONST(1000000000000)) |
|
3815
|
|
|
|
|
|
|
#endif |
|
3816
|
|
|
|
|
|
|
{ |
|
3817
|
1
|
|
|
|
|
|
r = 1 + urandomm64(ctx, n); |
|
3818
|
1
|
|
|
|
|
|
*nf = factor(r, factors); |
|
3819
|
1
|
|
|
|
|
|
return r; |
|
3820
|
|
|
|
|
|
|
} |
|
3821
|
|
|
|
|
|
|
do { /* Kalai's algorithm */ |
|
3822
|
|
|
|
|
|
|
for (s = n, r = 1, nfac = 0; s > 1; ) { |
|
3823
|
|
|
|
|
|
|
s = 1 + urandomm64(ctx, s); |
|
3824
|
|
|
|
|
|
|
if (!is_prime(s)) continue; |
|
3825
|
|
|
|
|
|
|
if (s > n / r) { r = 0; break; } /* overflow */ |
|
3826
|
|
|
|
|
|
|
r *= s; |
|
3827
|
|
|
|
|
|
|
factors[nfac++] = s; |
|
3828
|
|
|
|
|
|
|
} |
|
3829
|
|
|
|
|
|
|
} while (r == 0 || r > n || (1 + urandomm64(ctx,n)) > r); |
|
3830
|
|
|
|
|
|
|
*nf = nfac; |
|
3831
|
|
|
|
|
|
|
return r; |
|
3832
|
|
|
|
|
|
|
} |