結果
問題 | No.2349 Power!! (Hard) |
ユーザー | Forested |
提出日時 | 2023-06-05 21:38:38 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 3,332 ms / 7,000 ms |
コード長 | 5,536 bytes |
コンパイル時間 | 2,562 ms |
コンパイル使用メモリ | 170,960 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-06-10 12:32:01 |
合計ジャッジ時間 | 34,109 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 4 ms
5,248 KB |
testcase_01 | AC | 1,697 ms
5,376 KB |
testcase_02 | AC | 1,729 ms
5,376 KB |
testcase_03 | AC | 1,728 ms
6,940 KB |
testcase_04 | AC | 550 ms
6,940 KB |
testcase_05 | AC | 2,357 ms
6,944 KB |
testcase_06 | AC | 3,297 ms
6,944 KB |
testcase_07 | AC | 3,332 ms
6,944 KB |
testcase_08 | AC | 3,311 ms
6,944 KB |
testcase_09 | AC | 3,255 ms
6,940 KB |
testcase_10 | AC | 3,161 ms
6,944 KB |
testcase_11 | AC | 3,234 ms
6,940 KB |
testcase_12 | AC | 3,224 ms
6,940 KB |
ソースコード
#ifndef LOCAL #define FAST_IO #endif // ============ #include <algorithm> #include <array> #include <bitset> #include <cassert> #include <cmath> #include <iomanip> #include <iostream> #include <list> #include <map> #include <numeric> #include <queue> #include <random> #include <set> #include <stack> #include <string> #include <tuple> #include <unordered_map> #include <unordered_set> #include <utility> #include <vector> #define OVERRIDE(a, b, c, d, ...) d #define REP2(i, n) for (i32 i = 0; i < (i32)(n); ++i) #define REP3(i, m, n) for (i32 i = (i32)(m); i < (i32)(n); ++i) #define REP(...) OVERRIDE(__VA_ARGS__, REP3, REP2)(__VA_ARGS__) #define PER(i, n) for (i32 i = (i32)(n) - 1; i >= 0; --i) #define ALL(x) begin(x), end(x) using namespace std; using u32 = unsigned int; using u64 = unsigned long long; using i32 = signed int; using i64 = signed long long; using f64 = double; using f80 = long double; template <typename T> using Vec = vector<T>; template <typename T> bool chmin(T &x, const T &y) { if (x > y) { x = y; return true; } return false; } template <typename T> bool chmax(T &x, const T &y) { if (x < y) { x = y; return true; } return false; } #ifdef INT128 using u128 = __uint128_t; using i128 = __int128_t; istream &operator>>(istream &is, i128 &x) { i64 v; is >> v; x = v; return is; } ostream &operator<<(ostream &os, i128 x) { os << (i64)x; return os; } istream &operator>>(istream &is, u128 &x) { u64 v; is >> v; x = v; return is; } ostream &operator<<(ostream &os, u128 x) { os << (u64)x; return os; } #endif [[maybe_unused]] constexpr i32 INF = 1000000100; [[maybe_unused]] constexpr i64 INF64 = 3000000000000000100; struct SetUpIO { SetUpIO() { #ifdef FAST_IO ios::sync_with_stdio(false); cin.tie(nullptr); #endif cout << fixed << setprecision(15); } } set_up_io; // ============ #ifdef DEBUGF #else #define DBG(x) (void) 0 #endif // ============ // ============ #include <algorithm> #include <iostream> #include <atcoder/convolution> namespace poly { using Mint = atcoder::modint998244353; using Poly = std::vector<Mint>; Poly add(Poly f, Poly g) { if (f.size() < g.size()) { std::swap(f, g); } for (int i = 0; i < (int)g.size(); ++i) { f[i] += g[i]; } return f; } Poly sub(Poly f, Poly g) { if (f.size() < g.size()) { std::swap(f, g); } for (int i = 0; i < (int)g.size(); ++i) { f[i] -= g[i]; } return f; } Poly mul(const Poly &f, const Poly &g) { return atcoder::convolution(f, g); } void dft(Poly &f) { atcoder::internal::butterfly(f); } void idft(Poly &f) { atcoder::internal::butterfly_inv(f); Mint inv = Mint::raw(f.size()).inv(); for (Mint &cf : f) { cf *= inv; } } } // namespace poly // ============ namespace poly { std::vector<Mint> geometric_multipoint_evaluation(const Poly &f, int m, Mint a, Mint r) { int n = (int)f.size(); if (n == 0) { return std::vector<Mint>(m, Mint()); } if (m == 0) { return std::vector<Mint>(); } if (r == Mint()) { Mint ev; Mint p(1); for (int i = 0; i < n; ++i) { ev += f[i] * p; p *= a; } std::vector<Mint> ret(m, f[0]); ret[0] = ev; return ret; } std::vector<Mint> w(n + m - 1), w_inv(std::max(n, m)); { Mint v(1), pw(1); for (int i = 0; i < n + m - 1; ++i) { w[i] = v; v *= pw; pw *= r; } } { Mint inv = r.inv(); Mint v(1), pw(1); for (int i = 0; i < std::max(n, m); ++i) { w_inv[i] = v; v *= pw; pw *= inv; } } std::vector<Mint> y(n); { Mint pw(1); for (int i = 0; i < n; ++i) { y[i] = f[i] * pw * w_inv[i]; pw *= a; } } std::reverse(y.begin(), y.end()); std::vector<Mint> conv = mul(y, w); std::vector<Mint> ans(conv.begin() + (n - 1), conv.begin() + (n + m - 1)); for (int i = 0; i < m; ++i) { ans[i] *= w_inv[i]; } return ans; } } // namespace poly // ============ using poly::Mint; constexpr u32 P = 998244353; constexpr u32 D = 1 << 20; constexpr u32 E = P / D; Vec<Mint> mod_e(Mint a, i32 n) { i32 m = n / E; poly::Poly g(m); REP(i, m) { g[i] = a.pow((i64)E * E * i * i); } Vec<Mint> ans = poly::geometric_multipoint_evaluation(g, E, Mint::raw(1), a.pow(2 * E)); REP(i, E) { ans[i] *= a.pow((i64)i * i); } REP(i, m * E, n) { ans[i % E] += a.pow((i64)i * i); } return ans; } Mint part_1(Mint a, i32 l) { poly::Poly f(l); REP(i, l) { f[i] = a.pow((i64)D * D * i * i); } Vec<Mint> gme = poly::geometric_multipoint_evaluation(f, E, Mint::raw(1), a.pow(2 * D)); Vec<Mint> moe = mod_e(a, D); Mint ans; REP(i, E) { ans += gme[i] * moe[i]; } return ans; } Mint part_2(Mint a, i32 l, i32 r) { Vec<Mint> moe = mod_e(a, r); Mint ans; REP(i, E) { ans += a.pow((i64)2 * l * D * i) * moe[i]; } ans *= a.pow((i64)l * l * D * D); return ans; } Mint solve(Mint a, i32 n) { return part_1(a, n / D) + part_2(a, n / D, n % D); } int main() { i32 t; cin >> t; while (t--) { i32 a, n; cin >> a >> n; cout << solve(Mint::raw(a), n).val() << '\n'; } }