結果
問題 | No.2120 場合の数の下8桁 |
ユーザー | 👑 emthrm |
提出日時 | 2022-11-04 21:37:17 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,018 ms / 2,000 ms |
コード長 | 3,421 bytes |
コンパイル時間 | 2,339 ms |
コンパイル使用メモリ | 208,808 KB |
実行使用メモリ | 9,856 KB |
最終ジャッジ日時 | 2024-07-18 19:20:38 |
合計ジャッジ時間 | 23,374 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 996 ms
9,728 KB |
testcase_01 | AC | 983 ms
9,472 KB |
testcase_02 | AC | 984 ms
9,856 KB |
testcase_03 | AC | 994 ms
9,600 KB |
testcase_04 | AC | 1,018 ms
9,600 KB |
testcase_05 | AC | 984 ms
9,728 KB |
testcase_06 | AC | 986 ms
9,600 KB |
testcase_07 | AC | 985 ms
9,728 KB |
testcase_08 | AC | 992 ms
9,728 KB |
testcase_09 | AC | 992 ms
9,600 KB |
testcase_10 | AC | 1,001 ms
9,600 KB |
testcase_11 | AC | 998 ms
9,728 KB |
testcase_12 | AC | 985 ms
9,728 KB |
testcase_13 | AC | 985 ms
9,600 KB |
testcase_14 | AC | 987 ms
9,600 KB |
testcase_15 | AC | 984 ms
9,600 KB |
testcase_16 | AC | 986 ms
9,600 KB |
testcase_17 | AC | 984 ms
9,600 KB |
testcase_18 | AC | 994 ms
9,728 KB |
testcase_19 | AC | 992 ms
9,600 KB |
ソースコード
// https://ferin-tech.hatenablog.com/entry/2018/01/17/010829 #define __USE_MINGW_ANSI_STDIO 0 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define int ll typedef vector<int> VI; typedef vector<VI> VVI; typedef pair<int, int> PII; #define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i) #define REP(i, n) FOR(i, 0, n) #define ALL(x) x.begin(), x.end() #define IN(a, b, x) (a<=x&&x<b) #define PB push_back const ll LLINF = (1LL<<60); const int INF = (1LL<<30); const int MOD = 1000000007; template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); } template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); } template<class S,class T> ostream &operator <<(ostream& out,const pair<S,T>& a){ out<<'('<<a.first<<','<<a.second<<')'; return out; } int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // ax + by = gcd(a, b) となる {x, y, gcd(a, b)} を返す // O(log(min(a, b))) ll extgcd(ll a, ll b, ll &x, ll &y) { ll g = a; x = 1, y = 0; if(b != 0) g = extgcd(b, a%b, y, x), y -= (a/b) * x; return g; } // a^-1 mod n を返す 存在しなければ-1 // O(log(n)) ll inv(ll a, ll n) { ll s, t; extgcd(a, n, s, t); return (n+s) % n; } // 二分累乗法 x^e % mod O(log(e)) ll binpow(ll x, ll e, ll mod) { ll a = 1, p = x; while(e > 0) { if(e%2 == 0) {p = (p*p) % mod; e /= 2;} else {a = (a*p) % mod; e--;} } return a % mod; } // x = a1 mod m1, x2 = a2 mod m2 を解く オーバーフローには注意 // O(log(min(m1, m2))) pair<ll, ll> crt(ll a1, ll a2, ll m1, ll m2) { auto normal = [](ll x, ll m) { return x>=-x ? x%m : m-(-x)%m; }; auto modmul = [&normal](ll a, ll b, ll m) { return normal(a, m)*normal(b, m)%m; }; ll k1, k2; ll g = extgcd(m1, m2, k1, k2); if(normal(a1, g) != normal(a2, g)) return {-1, -1}; ll l = m1 / g * m2; ll x = a1 + modmul(modmul((a2-a1)/g, k1, l), m1, l); return {x, l}; } pair<ll, ll> crt(vector<ll> a, vector<ll> m) { ll mod = 1, ans = 0; int n = a.size(); REP(i, n) { tie(ans, mod) = crt(ans, a[i], mod, m[i]); if(ans == -1) return {-1, -1}; } return {ans, mod}; } ll fact[1000010], ifact[1000010]; void makeFac(ll p, ll q) { ll pr = 1; REP(i, q) pr *= p; fact[0] = ifact[0] = 1; FOR(i, 1, pr+1) { if(i%p == 0) { fact[i] = fact[i-1]; } else { fact[i] = fact[i-1] * i % pr; } ifact[i] = inv(fact[i], pr); } } ll C(ll n, ll r, ll p, ll q) { if(n < 0 || r < 0 || r > n) return 0; // pr = p^q int pr = 1; REP(i, q) pr *= p; ll z = n-r; int e0 = 0; for(ll u=n/p;u;u/=p) e0 += u; for(ll u=r/p;u;u/=p) e0 -= u; for(ll u=z/p;u;u/=p) e0 -= u; int em = 0; for(ll u=n/pr;u;u/=p) em += u; for(ll u=r/pr;u;u/=p) em -= u; for(ll u=z/pr;u;u/=p) em -= u; ll ret = 1; while(n > 0) { ret = ret*fact[n%pr]%pr*ifact[r%pr]%pr*ifact[z%pr]%pr; n /= p; r /= p; z /= p; } (ret *= binpow(p, e0, pr)) %= pr; if(!(p==2 && q >= 3) && em%2) ret = (pr-ret) % pr; return ret; } ll func(ll n, ll r, ll mod) { ll x = mod; vector<ll> a, m; FOR(i, 2, mod+1) if(x%i == 0) { ll cnt=0, pr=1; while(x%i==0) x/=i, cnt++, pr*=i; makeFac(i, cnt); a.PB(C(n, r, i, cnt)); m.PB(pr); } return crt(a, m).first; } signed main(void) { ll n, m; cin >> n >> m; const string ans = to_string(func(n, m, 100000000)); cout << string(8 - ans.length(), '0') << ans << '\n'; return 0; }