結果

問題 No.2120 場合の数の下8桁
ユーザー umezoumezo
提出日時 2023-01-19 06:44:40
言語 C++17(gcc12)
(gcc 12.3.0 + boost 1.87.0)
結果
RE  
実行時間 -
コード長 6,607 bytes
コンパイル時間 2,559 ms
コンパイル使用メモリ 212,392 KB
実行使用メモリ 339,136 KB
最終ジャッジ日時 2024-06-12 18:51:48
合計ジャッジ時間 11,132 ms
ジャッジサーバーID
(参考情報)
judge3 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,812 KB
testcase_01 AC 2 ms
6,812 KB
testcase_02 AC 1 ms
6,944 KB
testcase_03 AC 2 ms
6,944 KB
testcase_04 AC 2 ms
6,940 KB
testcase_05 AC 2 ms
6,944 KB
testcase_06 AC 1,258 ms
339,124 KB
testcase_07 AC 1 ms
6,940 KB
testcase_08 RE -
testcase_09 AC 10 ms
6,944 KB
testcase_10 AC 553 ms
167,360 KB
testcase_11 AC 1,181 ms
339,136 KB
testcase_12 AC 2 ms
6,940 KB
testcase_13 AC 9 ms
6,940 KB
testcase_14 AC 24 ms
10,112 KB
testcase_15 AC 535 ms
164,752 KB
testcase_16 AC 1,117 ms
322,076 KB
testcase_17 AC 1,227 ms
332,748 KB
testcase_18 WA -
testcase_19 AC 1,190 ms
339,008 KB
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(v) v.begin(),v.end()
typedef long long ll;
#include <bits/stdc++.h>
using namespace std;
class LinearSieve {
public:
LinearSieve(unsigned int n) : _n(n), min_prime_factor(std::vector<unsigned int>(n + 1)) {
std::iota(min_prime_factor.begin(), min_prime_factor.end(), 0);
prime_list.reserve(_n + 1);
for (unsigned int d = 2; d <= _n; ++d) {
if (min_prime_factor[d] == d) {
prime_list.push_back(d);
}
unsigned int prime_max = std::min(min_prime_factor[d], _n / d);
for (unsigned int prime : prime_list) {
if (prime > prime_max) {
break;
}
min_prime_factor[prime * d] = prime;
}
}
}
unsigned int prime_num() const {
return prime_list.size();
}
const std::vector<unsigned int>& get_prime_list() const {
return prime_list;
}
const std::vector<unsigned int>& get_min_prime_factor() const {
return min_prime_factor;
}
private:
const unsigned int _n;
std::vector<unsigned int> min_prime_factor;
std::vector<unsigned int> prime_list;
};
// nCk mod m k = 0, ..., n m
class ArbitraryModBinomialCoefficients {
public:
// nCk mod m
ArbitraryModBinomialCoefficients(unsigned int N, unsigned int M) :
_N(N), _M(M), _sieve(LinearSieve(N)), _binom(std::vector<long long>(N + 1)) {
solve();
}
// return nCk
long long operator[](unsigned int k) const {
return _binom[k];
}
// return nC0, nC1, ..., nCn mod m vector
const std::vector<long long>& get_coeffs() const {
return _binom;
}
//
const LinearSieve& get_sieve() const {
return _sieve;
}
private:
const unsigned int _N, _M;
const LinearSieve _sieve;
std::vector<long long> _binom;
// return y = (x mod M) (0 <= y < M)
inline unsigned int safe_mod(const long long x) {
int y = x % _M;
return y < 0 ? y + _M : y;
}
// return x s.t. 0 <= x < m and (v * x mod m) = gcd(a, m)
unsigned int gcd_inv(const unsigned int v) {
long long a = v, b = _M;
long long x = 1, z = 0;
long long y = 0, w = 1;
long long tmp;
while (b) {
long long p = a / b, q = a % b;
tmp = x - z * p; x = z; z = tmp;
tmp = y - w * p; y = w; w = tmp;
a = b; b = q;
}
return safe_mod(x);
}
// reference: https://37zigen.com/linear-sieve/
// mod
//
void mod_invs(std::vector<long long>& invs) {
auto &mpf = _sieve.get_min_prime_factor();
for (unsigned int i = 0; i <= _N; ++i) {
unsigned int pf = mpf[i];
if (pf == i) {
invs[i] = gcd_inv(i);
} else {
invs[i] = invs[pf] * invs[i / pf] % _M;
}
}
}
void solve() {
// sieve
//
auto &primes = _sieve.get_prime_list();
// d p
std::vector<unsigned int> d(_N + 1, 0);
std::vector<unsigned int> p;
for (unsigned int prime : primes) {
if (_M % prime) continue;
p.push_back(prime);
unsigned int sz = p.size();
for (unsigned int v = prime; v <= _N; v += prime) {
d[v] = sz;
}
}
const unsigned int L = p.size();
// p 1-indexed
p.insert(p.begin(), 0);
// invs[k] = k ^ {-1} mod M ()
//
std::vector<long long> invs(_N + 1);
mod_invs(invs);
//
std::vector<std::vector<long long>> powers(L + 1);
for (unsigned int i = 1; i <= L; ++i) {
// ()
unsigned int max_index = _N / (p[i] - 1);
powers[i].resize(max_index + 1);
powers[i][0] = 1;
for (unsigned int j = 0; j < max_index; ++j) {
powers[i][j + 1] = powers[i][j] * p[i] % _M;
}
}
//
const unsigned int half = (_N + 1) / 2;
// k = 0 S, T
long long S = 1;
std::vector<unsigned int> T(L + 1, 0);
// nC0 = 1
_binom[0] = 1;
for (unsigned int k = 1; k <= half; ++k) {
// num: , den:
unsigned int num = _N - k + 1, den = k;
// T
// t T 使
while (d[num]) ++T[d[num]], num /= p[d[num]];
while (d[den]) --T[d[den]], den /= p[d[den]];
// S
S = S * num % _M;
S = S * invs[den] % _M;
// S, T nCk
_binom[k] = S;
for (unsigned int i = 1; i <= L; ++i) {
_binom[k] = _binom[k] * powers[i][T[i]] % _M;
}
}
// nCk = nCn-k
for (unsigned int k = half + 1; k <= _N; ++k) {
_binom[k] = _binom[_N - k];
}
}
};
int main(){
ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int m,n;
cin>>m>>n;
ArbitraryModBinomialCoefficients C(m,1e8);
printf("%08d\n",C[n]);
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0