結果
問題 | No.1973 Divisor Sequence |
ユーザー |
![]() |
提出日時 | 2022-06-13 01:01:18 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 13 ms / 2,000 ms |
コード長 | 3,393 bytes |
コンパイル時間 | 609 ms |
コンパイル使用メモリ | 55,424 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-09-24 14:37:24 |
合計ジャッジ時間 | 1,553 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 22 |
ソースコード
/* -*- coding: utf-8 -*-** 1973.cc: No.1973 Divisor Sequence - yukicoder*/#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;/* constant */const int MAX_N = 500000 + 50;const int MAX_K = 41;const int MAX_P = 1000000 + 100;const int MOD = 1000000007;/* typedef */typedef long long ll;typedef vector<int> vi;template<const int MOD>struct MI {int v;MI(): v() {}MI(int _v): v(_v % MOD) {}MI(long long _v): v(_v % MOD) {}MI operator+(const MI m) const { return MI(v + m.v); }MI operator-(const MI m) const { return MI(v + MOD - m.v); }MI operator*(const MI m) const { return MI((long long)v * m.v); }MI &operator+=(const MI m) { return (*this = *this + m); }MI &operator-=(const MI m) { return (*this = *this - m); }MI &operator*=(const MI m) { return (*this = *this * m); }MI pow(int n) const { // a^n % MODMI pm = 1, a = *this;while (n > 0) {if (n & 1) pm *= a;a *= a;n >>= 1;}return pm;}MI inv() const { return pow(MOD - 2); }MI operator/(const MI m) const { return *this * m.inv(); }MI &operator/=(const MI m) { return (*this = *this / m); }};typedef MI<MOD> mi;typedef mi vec[MAX_K];typedef vec mat[MAX_K];/* global variables */bool primes[MAX_P + 1];int cache[MAX_K];/* subroutines */int gen_primes(int maxp, vi &pnums) {memset(primes, true, sizeof(primes));primes[0] = primes[1] = false;int p;for (p = 2; p * p <= maxp; p++)if (primes[p]) {pnums.push_back(p);for (int q = p * p; q <= maxp; q += p) primes[q] = false;}for (; p <= maxp; p++)if (primes[p]) pnums.push_back(p);return (int)pnums.size();}void prime_decomp(ll n, vi &pnums, vi& pds) {pds.clear();for (auto pi: pnums) {if ((ll)pi * pi > n) break;if (n % pi == 0) {int fi = 0;while (n % pi == 0) n /= pi, fi++;pds.push_back(fi);}}if (n > 1) pds.push_back(1);}inline void initmat(const int n, mat a) { memset(a, 0, sizeof(mat)); }inline void unitmat(const int n, mat a) {initmat(n, a);for (int i = 0; i < n; i++) a[i][i] = 1;}inline void copymat(const int n, const mat a, mat b) {memcpy(b, a, sizeof(mat));}inline void mulmat(const int n, const mat a, const mat b, mat c) {for (int i = 0; i < n; i++)for (int j = 0; j < n; j++) {c[i][j] = 0;for (int k = 0; k < n; k++)c[i][j] += a[i][k] * b[k][j];}}inline void powmat(const int n, const mat a, int b, mat c) {mat s, t;copymat(n, a, s);unitmat(n, c);while (b > 0) {if (b & 1) {mulmat(n, c, s, t);copymat(n, t, c);}mulmat(n, s, s, t);copymat(n, t, s);b >>= 1;}}mi calc(int k, int n) {if (cache[k] >= 0) return mi(cache[k]);mat ma, mb;for (int i = 0; i < k; i++)for (int j = 0; j < k; j++) ma[i][j] = (i + j < k) ? 1 : 0;powmat(k, ma, n, mb);mi sum = 0;for (int i = 0; i < k; i++) sum += mb[i][0];cache[k] = sum.v;return sum;}/* main */int main() {vi pnums;gen_primes(MAX_P, pnums);int n;ll m;scanf("%d%lld", &n, &m);vi pds;prime_decomp(m, pnums, pds);//for (auto f: pds) printf("%d ", f); putchar('\n');fill(cache, cache + MAX_K, -1);mi p = 1;for (auto f: pds) p *= calc(f + 1, n);printf("%d\n", p.v);return 0;}