Pagini recente » Rezultatele filtrării | Cod sursa (job #2628927) | Cod sursa (job #740496) | Cod sursa (job #2654377) | Cod sursa (job #3302093)
#include <stdio.h>
#include <inttypes.h>
#define PRIME_P UINT64_C(2000003)
uint64_t modular_inverse (uint64_t a) {
uint64_t e = 0;
uint64_t b = 0;
uint64_t p = 0;
uint64_t x = 0;
e = PRIME_P - 2;
b = 1; // b: 2ᵏ, for k := 0, 1, …, ⌊log₂(e)⌋
p = a; // p: aᵇ
x = 1;
while (0 != e) {
if (0 != (b & e)) {
x *= p;
x %= PRIME_P;
e ^= b;
}
b += b;
p *= p;
p %= PRIME_P;
}
return x;
}
int main (void) {
FILE * f = NULL;
FILE * g = NULL;
uint64_t k = 0;
uint64_t n = 0;
uint64_t m = 0;
uint64_t j = 0;
uint64_t q = 0;
uint64_t a = 0;
uint64_t b = 0;
uint64_t c = 0;
uint64_t w = 0;
f = fopen("sandokan.in", "r");
g = fopen("sandokan.out", "w");
(void) fscanf(f, "%" SCNu64 "%" SCNu64, &n, &k);
/* (ⁿ⁻¹ ₘ₋₁) = (n − 1)!·((n − m)!)⁻¹·((m − 1)!)⁻¹
*
* a: (n − m)!, b: (m − 1)!, c: (n − 1)!
*
* w: c·b⁻¹·a⁻¹ (mod PRIME_P); w is the answer.
*
* m = k − 1, when n is a multiple of k − 1, and n % (k − 1), otherwise,
* because each possibility is a subset of containing any m − 1 elements of
* the initial set without its max element, and the initial max element.
*
*/
if (0 != (n % (k - 1))) {
m = n % (k - 1);
}
else {
m = k - 1;
}
j = 0;
q = 1; // q: j!
while (j < n) {
if (j == (n - m)) { a = q; }
if (j == (m - 1)) { b = q; }
if (j == (n - 1)) { c = q; }
j += 1;
q *= j;
q %= PRIME_P;
}
w = c; w %= PRIME_P;
w *= modular_inverse(b); w %= PRIME_P;
w *= modular_inverse(a); w %= PRIME_P;
(void) fprintf(g, "%" PRIu64 "\n", w);
(void) fclose(g);
(void) fclose(f);
return 0;
}