結果
問題 | No.2883 K-powered Sum of Fibonacci |
ユーザー |
|
提出日時 | 2025-01-12 18:54:10 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 228 ms / 3,000 ms |
コード長 | 10,427 bytes |
コンパイル時間 | 8,086 ms |
コンパイル使用メモリ | 350,468 KB |
実行使用メモリ | 6,144 KB |
最終ジャッジ日時 | 2025-01-12 18:54:23 |
合計ジャッジ時間 | 12,389 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 40 |
ソースコード
#ifndef ONLINE_JUDGE #define _GLIBCXX_DEBUG #endif #include "atcoder/all" #include <string> #include <bits/stdc++.h> #include <climits> /* Boostが使用したかったら WSLの方で開いて #include <boost/multiprecision/cpp_dec_float.hpp> #include <boost/multiprecision/cpp_int.hpp> #include <boost/rational.hpp> #include <boost/functional/hash.hpp> // 任意長整数型 using Bint = boost::multiprecision::cpp_int; // 仮数部が10進数で1024桁の浮動小数点数型(TLEしたら小さくする) using BReal = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<1024>>; using Rat = boost::rational<Bint>; */ #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; // 型エイリアスの設定 template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; using namespace atcoder; template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; } template<typename T> inline bool chmin(T &a, T b) { return ((a>b) ? (a = b, true) : (false));} #define rep(i,n) for(int i=0;i<(int)(n);i++) #define drep(i,n) for(int i=n-1;i>=0;i--) #define REP(i,s,n) for(int i=s;i<(int)n;i++) #define DREP(i,s,n) for(int i=n-1;i>=s;i--) const long long inf = 1LL<<60; const int infi = 1e9+1; typedef long long ll; typedef long double ld; typedef __int128_t l3; //cmpArg := 偏角ソート, atan2l(y, x); atan2l(y, x) = [-pi, pi] #define cmpArg [](const auto &p1, const auto &p2) { return atan2l(p1.second, p1.first) < atan2l(p2.second, p2.first); } typedef pair<int,int> pi; typedef pair<ll,ll> pl; #define vl vector<ll> #define vvl vector<vector<ll>> #define vi vector<int> #define vvi vector<vector<int>> #define vm vector<mint> #define vvm vector<vector<mint>> #define vvc vector<vector<char>> #define vc vector<char> #define vvpi vector<vector<pi>> #define vpi vector<pi> #define vpl vector<pl> #define vvpl vector<vector<pl>> #define pb push_back #define eb emplace_back #define YES cout<<"Yes"<<endl; #define NO cout<<"No"<<endl; #define YN { cout << "Yes" << endl; } else { cout << "No" << endl; } #define all(x) x.begin(), x.end() #define rall(i) std::rbegin(i), std::rend(i) #define len(x) ((ll)(x).size()) #define fi first #define se second #define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()) int pc(ll x) { return __builtin_popcount(x); } //ビット列にどれだけ1がたっているかを求める pop count void cincout(){ ios::sync_with_stdio(false); std::cin.tie(nullptr); cout<< fixed << setprecision(15); } bool out_grid(ll i, ll j, ll h, ll w) { return (!(0<=i && i<h && 0<=j && j<w)); } inline void read(int &a) { std::cin >> a; } inline void read(unsigned &a) { std::cin >> a; } inline void read(long &a) { std::cin >> a; } inline void read(long long &a) { std::cin >> a; } inline void read(unsigned long long &a) { std::cin >> a; } inline void read(char &a) { std::cin >> a; } inline void read(float &a) { std::cin >> a; } inline void read(double &a) { std::cin >> a; } inline void read(long double &a) { std::cin >> a; } inline void read(std::vector<bool> &vec) { for (int32_t i = 0; i < vec.size(); i++) { int a; read(a); vec[i] = a; } } inline void read(std::string &a) { std::cin >> a; } template <class T> inline void read(std::vector<T> &vec); template <class T, size_t size> inline void read(std::array<T, size> &vec); template <class T, class L> inline void read(std::pair<T, L> &p); template <class T, size_t size> inline void read(T (&vec)[size]); template <class T> inline void read(std::vector<T> &vec) { for (auto &i : vec) read(i); } template <class T> inline void read(std::deque<T> &vec) { for (auto &i : vec) read(i); } template <class T, size_t size> inline void read(std::array<T, size> &vec) { for (auto &i : vec) read(i); } template <class T, class L> inline void read(std::pair<T, L> &p) { read(p.first); read(p.second); } template <class T, size_t size> inline void read(T (&vec)[size]) { for (auto &i : vec) read(i); } template <class T> inline void read(T &a) { std::cin >> a; } inline void in() {} template <class Head, class... Tail> inline void in(Head &head, Tail &...tail) { read(head); in(tail...); } inline void print() { std::cout << ' '; } inline void print(const bool &a) { std::cout << a; } inline void print(const int &a) { std::cout << a; } inline void print(const unsigned &a) { std::cout << a; } inline void print(const long &a) { std::cout << a; } inline void print(const long long &a) { std::cout << a; } inline void print(const unsigned long long &a) { std::cout << a; } inline void print(const char &a) { std::cout << a; } inline void print(const char a[]) { std::cout << a; } inline void print(const float &a) { std::cout << a; } inline void print(const double &a) { std::cout << a; } inline void print(const long double &a) { std::cout << a; } inline void print(const std::string &a) { for (auto &&i : a) print(i); } template <class T> inline void print(const std::vector<T> &vec); template <class T, size_t size> inline void print(const std::array<T, size> &vec); template <class T, class L> inline void print(const std::pair<T, L> &p); template <class T, size_t size> inline void print(const T (&vec)[size]); template <class T> inline void print(const std::vector<T> &vec) { if (vec.empty()) return; print(vec[0]); for (auto i = vec.begin(); ++i != vec.end();) { std::cout << ' '; print(*i); } } template <class T> inline void print(const std::deque<T> &vec) { if (vec.empty()) return; print(vec[0]); for (auto i = vec.begin(); ++i != vec.end();) { std::cout << ' '; print(*i); } } template <class T, size_t size> inline void print(const std::array<T, size> &vec) { print(vec[0]); for (auto i = vec.begin(); ++i != vec.end();) { std::cout << ' '; print(*i); } } template <class T, class L> inline void print(const std::pair<T, L> &p) { print(p.first); std::cout << ' '; print(p.second); } template <class T, size_t size> inline void print(const T (&vec)[size]) { print(vec[0]); for (auto i = vec; ++i != end(vec);) { std::cout << ' '; print(*i); } } template <class T> inline void print(const T &a) { std::cout << a; } inline void out() { std::cout << '\n'; } template <class T> inline void out(const T &t) { print(t); std::cout << '\n'; } template <class Head, class... Tail> inline void out(const Head &head, const Tail &...tail) { print(head); std::cout << ' '; out(tail...); } #define vec(type, name, ...) vector<type> name(__VA_ARGS__); #define vv(type, name, h, ...) std::vector<std::vector<type>> name(h, std::vector<type>(__VA_ARGS__)); #define INT(...) int32_t __VA_ARGS__; in(__VA_ARGS__) #define LL(...) int64_t __VA_ARGS__; in(__VA_ARGS__) #define ULL(...) uint64_t __VA_ARGS__; in(__VA_ARGS__) #define STR(...) std::string __VA_ARGS__; in(__VA_ARGS__) #define CHR(...) char __VA_ARGS__; in(__VA_ARGS__) #define LD(...) long double __VA_ARGS__; in(__VA_ARGS__) #define VEC(type, name, size) std::vector<type> name(size); in(name) #define VV(type, name, h, w) std::vector<std::vector<type>> name(h, std::vector<type>(w)); in(name) template <class T> ll sum(const T &a) { return accumulate(std::begin(a), std::end(a), 0LL); } template <class T> ld dsum(const T &a) { return accumulate(std::begin(a), std::end(a), 0.0L); } template <class T> auto min(const T &a) { return *min_element(std::begin(a), std::end(a)); } template <class T> auto max(const T &a) { return *max_element(std::begin(a), std::end(a)); } template<typename T> T floor_div(const T n, const T d) { assert(d != 0); return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0); } template<typename T> T ceil_div(const T n, const T d) { assert(d != 0); return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0); } using mint = modint998244353; template<typename T> struct Matrix { int h, w; vector<vector<T>> d; Matrix() {} Matrix(int h, int w, T val=0): h(h), w(w), d(h, vector<T>(w,val)) {} Matrix& unit() { assert(h == w); rep(i,h) d[i][i] = 1; return *this; } const vector<T>& operator[](int i) const { return d[i];} vector<T>& operator[](int i) { return d[i];} Matrix operator*(const Matrix& a) const { assert(w == a.h); Matrix r(h, a.w); rep(i,h)rep(k,w)rep(j,a.w) { r[i][j] += d[i][k]*a[k][j]; } return r; } Matrix pow(long long t) const { assert(h == w); if (!t) return Matrix(h,h).unit(); if (t == 1) return *this; Matrix r = pow(t>>1); r = r*r; if (t&1) r = r*(*this); return r; } // https://youtu.be/-j02o6__jgs?t=11273 mint det() { assert(h == w); mint res = 1; rep(k,h) { for (int i = k; i < h; ++i) { if (d[i][k] == 0) continue; if (i != k) { swap(d[i],d[k]); res = -res; } } if (d[k][k] == 0) return 0; res *= d[k][k]; mint inv = mint(1)/d[k][k]; rep(j,h) d[k][j] *= inv; for (int i = k+1; i < h; ++i) { mint c = d[i][k]; for (int j = k; j < h; ++j) d[i][j] -= d[k][j]*c; } } return res; } }; const ll MAX = 101010; const ll MOD = 998244353; long long fac[MAX], finv[MAX], inv[MAX]; // テーブルを作る前処理 void COMinit() { fac[0] = fac[1] = 1; //累積積 finv[0] = finv[1] = 1; //逆元の累積積 inv[1] = 1; //逆元 for (int i = 2; i < MAX; i++){ fac[i] = fac[i - 1] * i % MOD; inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD; finv[i] = finv[i - 1] * inv[i] % MOD; } } // 二項係数計算 long long COM(ll n, ll k){ if (n < k) return 0; if (n < 0 || k < 0) return 0; return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD; } long long PER(ll n, ll k) { if(n < k) return 0; if(n < 0 || k < 0) return 0; return (fac[n] * finv[n-k]) % MOD; } int main() { COMinit(); LL(N,K); Matrix<mint> mat(K+2,K+2,0); mat[0][0] = 1; mat[0][1] = 1; for(int i=1;i<=K+1;i++) { int t = K-i+1; for(int j=1;j<=K+1;j++) { int s = t-j+1; mat[i][j] = COM(t,s); } } Matrix<mint> dp(K+2,1,0); dp[1][0] = 1; dp = mat.pow(N) * dp; out(dp[0][0].val()); }