結果
問題 | No.109 N! mod M |
ユーザー | bal4u |
提出日時 | 2019-04-21 07:56:09 |
言語 | C (gcc 12.3.0) |
結果 |
AC
|
実行時間 | 81 ms / 5,000 ms |
コード長 | 2,162 bytes |
コンパイル時間 | 250 ms |
コンパイル使用メモリ | 31,360 KB |
実行使用メモリ | 6,820 KB |
最終ジャッジ日時 | 2024-10-04 17:53:32 |
合計ジャッジ時間 | 1,012 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,816 KB |
testcase_01 | AC | 32 ms
6,820 KB |
testcase_02 | AC | 43 ms
6,816 KB |
testcase_03 | AC | 1 ms
6,820 KB |
testcase_04 | AC | 2 ms
6,820 KB |
testcase_05 | AC | 81 ms
6,820 KB |
testcase_06 | AC | 1 ms
6,816 KB |
testcase_07 | AC | 4 ms
6,820 KB |
testcase_08 | AC | 1 ms
6,820 KB |
コンパイルメッセージ
main.c: In function 'in': main.c:8:14: warning: implicit declaration of function 'getchar_unlocked' [-Wimplicit-function-declaration] 8 | #define gc() getchar_unlocked() | ^~~~~~~~~~~~~~~~ main.c:16:24: note: in expansion of macro 'gc' 16 | int n = 0, c = gc(); | ^~ main.c: In function 'out': main.c:9:15: warning: implicit declaration of function 'putchar_unlocked' [-Wimplicit-function-declaration] 9 | #define pc(c) putchar_unlocked(c) | ^~~~~~~~~~~~~~~~ main.c:26:17: note: in expansion of macro 'pc' 26 | if (!n) pc('0'); | ^~
ソースコード
// yukicoder: No.109 N! mod M // 2019.4.21 bal4u #include <stdio.h> //// 高速入力 #if 1 #define gc() getchar_unlocked() #define pc(c) putchar_unlocked(c) #else #define gc() getchar() #define pc(c) putchar(c) #endif int in() // 非負整数の入力 { int n = 0, c = gc(); do n = 10 * n + (c & 0xf), c = gc(); while (c >= '0'); return n; } void out(int n) // 非負整数の表示(出力) { int i; char b[20]; if (!n) pc('0'); else { i = 0; while (n) b[i++] = n % 10 + '0', n /= 10; while (i--) pc(b[i]); } pc('\n'); } //// 素数テスト long long calc_pow(int a, int k, int n) { long long p; unsigned bit; p = 1; for (bit = 0x80000000U; bit > 0; bit >>= 1) { if (p > 1) p = (p*p) % n; if (k & bit) p = (p*a) % n; } return p % n; } int suspect(int b, int n) { int i, t, u, n1; long long x0, x1; u = n1 = n - 1; t = 0; while ((u & 1) == 0) { t++; u >>= 1; } x0 = calc_pow(b, u, n); for (i = 1; i <= t; i++) { x1 = (x0*x0) % n; if (x1 == 1 && x0 != 1 && x0 != n1) return 0; x0 = x1; } return x1 == 1; } int prime_test(int n) { if (n == 1) return 0; /* 1 */ if (n == 2 || n == 3) return 1; /* 2, 3 */ if ((n & 1) == 0) return 0; /* other even integers */ if (!suspect(2, n)) return 0; if (n <= 1000000) { if (!suspect(3, n)) return 0; } else { if (!suspect(7, n)) return 0; if (!suspect(61, n)) return 0; } return 1; } //// 逆数の計算 int extended_gcd(int a, int b, int *x, int *y) { int d; if (b == 0) { *x = 1; *y = 0; return a; } d = extended_gcd(b, a % b, y, x); *y -= a / b * (*x); return d; } int inverse(int a, int m) { int x, y; extended_gcd(a, m, &x, &y); return (x + m) % m; } //// 本問題関連 int main() { int i, T, N, M; long long a, ans; T = in(); while (T--) { N = in(), M = in(); if (N >= M || M == 1) ans = 0; else if (N == 0) ans = 1; else if (N <= 100000) { ans = 1; for (i = 2; i <= N; i++) ans = ans * i % M; } else if (!prime_test(M)) ans = 0; else { a = 1; for (i = N+1; i < M; i++) a = a * i % M; ans = (long long)(M-1) * inverse((int)a, M) % M; } out((int)ans); } return 0; }