結果

問題 No.109 N! mod M
ユーザー codershifthcodershifth
提出日時 2015-10-06 00:22:49
言語 C++11
(gcc 11.4.0)
結果
WA  
実行時間 -
コード長 2,646 bytes
コンパイル時間 1,712 ms
コンパイル使用メモリ 160,784 KB
実行使用メモリ 6,944 KB
最終ジャッジ日時 2024-07-20 01:21:07
合計ジャッジ時間 2,074 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 AC 14 ms
5,376 KB
testcase_02 AC 19 ms
5,376 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 AC 3 ms
5,376 KB
testcase_05 AC 86 ms
5,376 KB
testcase_06 AC 4 ms
5,376 KB
testcase_07 WA -
testcase_08 AC 2 ms
5,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>

typedef long long ll;
typedef unsigned long long ull;

#define FOR(i,a,b) for(int (i)=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define RANGE(vec) (vec).begin(),(vec).end()

using namespace std;

bool isPrime(int n) {
        for (int i = 2; i*i <= n; ++i)
        {
            if (n%i==0)
                return false;
        }
        return (n!=1);
}
template<typename T>
T extgcd(T a, T b, T &x, T &y)
{
    T d = a;
    if (b != 0)
    {
        d = extgcd(b, a%b, y, x);
        y -= (a/b)*x;
    }
    else
    {
        x=1; y=0;
    }
    return d;
}
//  mod M の逆元を求める
ll mod_inverse(ll a, int M) {
        ll x, y;
        ll d = extgcd(a, (ll)M, x, y);
        assert(d == 1);
        return (M + x%M) % M;
}
class NFactorialModM {
public:
    void solve(void) {
            int T;
            cin>>T;

            //
            // N >= M なら N*(N-1)*...*(M+1)*M*(M-1)*...*1 = 0 mod M
            // N < M としてよい              ~~
            //
            // M-N <= 10^5 より
            // (M-1)!/N! = (M-1)*...*(N+1) は O(10^5) で計算可能
            //
            // N! = N!/(M-1)! * (M-1)! = (M-1)! * ((M-1)!/N!)^(-1) であることに留意する。
            //
            // * M が素数のときウィルソンの定理より
            //   (M-1)! == (M-1) mod M
            //
            // * M が合成数のとき M = (M/p) * p  とかける
            //  * M/p < N ならば N! で M が現れるので 0
            //  * M/p >= N ならば M >= p*N >= 2*N なので 10^5 > M-N >= N (N! 計算すればよい)
            //
            REP(t,T)
            {
                int N,M;
                cin>>N>>M;

                if (N >= M)
                {
                    cout<<0<<endl;
                    continue;
                }

                if (isPrime(M))
                {
                    ll a = 1;
                    for (int i = 1; i < M-N; ++i)
                        (a *= (N+i)) %= M;
                    cout<<(mod_inverse(a,M)*(M-1))%M<<endl;
                    continue;
                }
                if (M/2 < N)
                {
                    cout<<0<<endl;
                }
                else
                {
                    ll a = 1;
                    for (int i = 1; i <= N; ++i)
                        (a *= i) %= M;
                    cout<<a<<endl;
                }
            }
    }
};

#if 1
int main(int argc, char *argv[])
{
        ios::sync_with_stdio(false);
        auto obj = new NFactorialModM();
        obj->solve();
        delete obj;
        return 0;
}
#endif
0