結果
問題 | No.1659 Product of Divisors |
ユーザー | kimiyuki |
提出日時 | 2021-08-27 21:52:25 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 12 ms / 2,000 ms |
コード長 | 8,293 bytes |
コンパイル時間 | 2,446 ms |
コンパイル使用メモリ | 214,108 KB |
実行使用メモリ | 7,716 KB |
最終ジャッジ日時 | 2024-11-21 01:57:10 |
合計ジャッジ時間 | 3,287 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 11 ms
7,508 KB |
testcase_01 | AC | 12 ms
7,472 KB |
testcase_02 | AC | 12 ms
7,504 KB |
testcase_03 | AC | 11 ms
7,564 KB |
testcase_04 | AC | 12 ms
7,508 KB |
testcase_05 | AC | 12 ms
7,564 KB |
testcase_06 | AC | 11 ms
7,616 KB |
testcase_07 | AC | 11 ms
7,592 KB |
testcase_08 | AC | 11 ms
7,716 KB |
testcase_09 | AC | 11 ms
7,612 KB |
testcase_10 | AC | 11 ms
7,664 KB |
testcase_11 | AC | 11 ms
7,472 KB |
testcase_12 | AC | 11 ms
7,528 KB |
testcase_13 | AC | 11 ms
7,680 KB |
testcase_14 | AC | 12 ms
7,564 KB |
testcase_15 | AC | 12 ms
7,680 KB |
testcase_16 | AC | 11 ms
7,564 KB |
testcase_17 | AC | 12 ms
7,576 KB |
testcase_18 | AC | 11 ms
7,584 KB |
testcase_19 | AC | 11 ms
7,616 KB |
testcase_20 | AC | 11 ms
7,636 KB |
testcase_21 | AC | 11 ms
7,564 KB |
testcase_22 | AC | 11 ms
7,572 KB |
testcase_23 | AC | 10 ms
7,564 KB |
testcase_24 | AC | 11 ms
7,504 KB |
ソースコード
#line 1 "main.cpp" #include <bits/stdc++.h> #line 2 "/home/ubuntu/Library/utils/macros.hpp" #define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i)) #define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i)) #define REP_R(i, n) for (int i = (int)(n) - 1; (i) >= 0; -- (i)) #define REP3R(i, m, n) for (int i = (int)(n) - 1; (i) >= (int)(m); -- (i)) #define ALL(x) std::begin(x), std::end(x) #line 4 "/home/ubuntu/Library/modulus/modpow.hpp" inline int32_t modpow(uint_fast64_t x, uint64_t k, int32_t MOD) { assert (/* 0 <= x and */ x < (uint_fast64_t)MOD); uint_fast64_t y = 1; for (; k; k >>= 1) { if (k & 1) (y *= x) %= MOD; (x *= x) %= MOD; } assert (/* 0 <= y and */ y < (uint_fast64_t)MOD); return y; } #line 5 "/home/ubuntu/Library/modulus/modinv.hpp" inline int32_t modinv_nocheck(int32_t value, int32_t MOD) { assert (0 <= value and value < MOD); if (value == 0) return -1; int64_t a = value, b = MOD; int64_t x = 0, y = 1; for (int64_t u = 1, v = 0; a; ) { int64_t q = b / a; x -= q * u; std::swap(x, u); y -= q * v; std::swap(y, v); b -= q * a; std::swap(b, a); } if (not (value * x + MOD * y == b and b == 1)) return -1; if (x < 0) x += MOD; assert (0 <= x and x < MOD); return x; } inline int32_t modinv(int32_t x, int32_t MOD) { int32_t y = modinv_nocheck(x, MOD); assert (y != -1); return y; } #line 6 "/home/ubuntu/Library/modulus/mint.hpp" /** * @brief quotient ring / 剰余環 $\mathbb{Z}/n\mathbb{Z}$ */ template <int32_t MOD> struct mint { int32_t value; mint() : value() {} mint(int64_t value_) : value(value_ < 0 ? value_ % MOD + MOD : value_ >= MOD ? value_ % MOD : value_) {} mint(int32_t value_, std::nullptr_t) : value(value_) {} explicit operator bool() const { return value; } inline mint<MOD> operator + (mint<MOD> other) const { return mint<MOD>(*this) += other; } inline mint<MOD> operator - (mint<MOD> other) const { return mint<MOD>(*this) -= other; } inline mint<MOD> operator * (mint<MOD> other) const { return mint<MOD>(*this) *= other; } inline mint<MOD> & operator += (mint<MOD> other) { this->value += other.value; if (this->value >= MOD) this->value -= MOD; return *this; } inline mint<MOD> & operator -= (mint<MOD> other) { this->value -= other.value; if (this->value < 0) this->value += MOD; return *this; } inline mint<MOD> & operator *= (mint<MOD> other) { this->value = (uint_fast64_t)this->value * other.value % MOD; return *this; } inline mint<MOD> operator - () const { return mint<MOD>(this->value ? MOD - this->value : 0, nullptr); } inline bool operator == (mint<MOD> other) const { return value == other.value; } inline bool operator != (mint<MOD> other) const { return value != other.value; } inline mint<MOD> pow(uint64_t k) const { return mint<MOD>(modpow(value, k, MOD), nullptr); } inline mint<MOD> inv() const { return mint<MOD>(modinv(value, MOD), nullptr); } inline mint<MOD> operator / (mint<MOD> other) const { return *this * other.inv(); } inline mint<MOD> & operator /= (mint<MOD> other) { return *this *= other.inv(); } }; template <int32_t MOD> mint<MOD> operator + (int64_t value, mint<MOD> n) { return mint<MOD>(value) + n; } template <int32_t MOD> mint<MOD> operator - (int64_t value, mint<MOD> n) { return mint<MOD>(value) - n; } template <int32_t MOD> mint<MOD> operator * (int64_t value, mint<MOD> n) { return mint<MOD>(value) * n; } template <int32_t MOD> mint<MOD> operator / (int64_t value, mint<MOD> n) { return mint<MOD>(value) / n; } template <int32_t MOD> std::istream & operator >> (std::istream & in, mint<MOD> & n) { int64_t value; in >> value; n = value; return in; } template <int32_t MOD> std::ostream & operator << (std::ostream & out, mint<MOD> n) { return out << n.value; } #line 7 "/home/ubuntu/Library/number/primes.hpp" struct prepared_primes { int size; std::vector<int> sieve; std::vector<int> primes; /** * @note O(size) */ prepared_primes(int size_) : size(size_) { sieve.resize(size); REP3 (p, 2, size) if (sieve[p] == 0) { primes.push_back(p); for (int k = p; k < size; k += p) { if (sieve[k] == 0) { sieve[k] = p; } } } } /** * @note let k be the length of the result, O(k) if n < size; O(\sqrt{n} + k) if size <= n < size^2 */ std::vector<int64_t> list_prime_factors(int64_t n) const { assert (1 <= n and n < (int64_t)size * size); std::vector<int64_t> result; // trial division for large part for (int p : primes) { if (n < size or n < (int64_t)p * p) { break; } while (n % p == 0) { n /= p; result.push_back(p); } } // small part if (n == 1) { // nop } else if (n < size) { while (n != 1) { result.push_back(sieve[n]); n /= sieve[n]; } } else { result.push_back(n); } assert (std::is_sorted(ALL(result))); return result; } std::vector<int64_t> list_all_factors(int64_t n) const { auto p = list_prime_factors(n); std::vector<int64_t> d; d.push_back(1); for (int l = 0; l < p.size(); ) { int r = l + 1; while (r < p.size() and p[r] == p[l]) ++ r; int n = d.size(); REP (k1, r - l) { REP (k2, n) { d.push_back(d[d.size() - n] * p[l]); } } l = r; } return d; } /** * @note O(1) if n < size; O(sqrt n) if size <= n < size^2 */ bool is_prime(int64_t n) const { assert (1 <= n and n < (int64_t)size * size); if (n < size) { return sieve[n] == n; } for (int p : primes) { if (n < (int64_t)p * p) { break; } if (n % p == 0) { return false; } } return true; } }; #line 7 "/home/ubuntu/Library/number/primes_extra.hpp" std::map<int64_t, int> list_prime_factors_as_map(const prepared_primes& primes, int64_t n) { std::map<int64_t, int> cnt; for (int64_t p : primes.list_prime_factors(n)) { ++ cnt[p]; } return cnt; } int64_t euler_totient(const prepared_primes& primes, int64_t n) { int64_t phi = 1; int64_t last = -1; for (int64_t p : primes.list_prime_factors(n)) { if (last != p) { last = p; phi *= p - 1; } else { phi *= p; } } return phi; } #line 5 "/home/ubuntu/Library/modulus/choose_simple.hpp" /** * @brief combination / 組合せ ${} _ n C _ r$ (愚直 $O(r)$) */ template <int32_t MOD> mint<MOD> choose_simple(int64_t n, int32_t r) { assert (0 <= r and r <= n); mint<MOD> num = 1; mint<MOD> den = 1; REP (i, r) { num *= n - i; den *= i + 1; } return num / den; } #line 5 "/home/ubuntu/Library/modulus/multichoose_simple.hpp" /** * @brief 重複組合せ ${} _ n H _ r = {} _ {n + r - 1} C _ r$ (愚直 $O(r)$) */ template <int32_t MOD> mint<MOD> multichoose_simple(int64_t n, int32_t r) { assert (0 <= n and 0 <= r); if (n == 0 and r == 0) return 1; return choose_simple<MOD>(n + r - 1, r); } #line 7 "main.cpp" using namespace std; prepared_primes primes(1e6 + 100); constexpr int64_t MOD = 1000000007; mint<MOD> solve(int64_t n, int64_t k) { mint<MOD> ans = 1; for (auto [p, e] : list_prime_factors_as_map(primes, n)) { // ans *= multichoose_simple<MOD>(k, e); mint<MOD> y = 0; REP (x, e + 1) { y += multichoose_simple<MOD>(k, x); } ans *= y; } return ans; } // generated by oj-template v4.8.0 (https://github.com/online-judge-tools/template-generator) int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int64_t N, K; std::cin >> N >> K; auto ans = solve(N, K); std::cout << ans << '\n'; return 0; }