結果
問題 | No.1552 Simple Dice Game |
ユーザー | naskya |
提出日時 | 2021-06-19 12:58:52 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 332 ms / 2,500 ms |
コード長 | 29,493 bytes |
コンパイル時間 | 1,387 ms |
コンパイル使用メモリ | 137,896 KB |
実行使用メモリ | 7,168 KB |
最終ジャッジ日時 | 2024-06-22 21:57:52 |
合計ジャッジ時間 | 5,980 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 2 ms
6,940 KB |
testcase_03 | AC | 319 ms
7,040 KB |
testcase_04 | AC | 2 ms
6,944 KB |
testcase_05 | AC | 2 ms
6,940 KB |
testcase_06 | AC | 2 ms
6,944 KB |
testcase_07 | AC | 2 ms
6,940 KB |
testcase_08 | AC | 2 ms
6,940 KB |
testcase_09 | AC | 251 ms
6,940 KB |
testcase_10 | AC | 285 ms
7,040 KB |
testcase_11 | AC | 293 ms
6,940 KB |
testcase_12 | AC | 89 ms
6,944 KB |
testcase_13 | AC | 244 ms
6,944 KB |
testcase_14 | AC | 141 ms
6,940 KB |
testcase_15 | AC | 186 ms
6,940 KB |
testcase_16 | AC | 27 ms
6,940 KB |
testcase_17 | AC | 42 ms
6,940 KB |
testcase_18 | AC | 233 ms
6,940 KB |
testcase_19 | AC | 330 ms
7,168 KB |
testcase_20 | AC | 332 ms
7,168 KB |
testcase_21 | AC | 330 ms
7,168 KB |
testcase_22 | AC | 327 ms
7,168 KB |
testcase_23 | AC | 327 ms
7,168 KB |
コンパイルメッセージ
main.cpp: In member function 'constexpr lib::static_modint<modulo> lib::static_modint<modulo>::pow(Tp) const': main.cpp:517:72: warning: expected 'template' keyword before dependent template name [-Wmissing-template-keyword] 517 | if (index < 0) return static_modint<modulo>(value, true).inv().pow<true>(-index); | ^~~
ソースコード
#pragma region template // clang-format off #ifdef LOCAL_NDEBUG #include <headers.hpp> #endif // #define USE_EXTERNAL_CONTAINERS // #define NO_PRINT_INF #ifdef USE_EXTERNAL_CONTAINERS #define PROPER #include <boost/container/flat_map.hpp> #include <boost/container/flat_set.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> template <class T> using rb_tree = __gnu_pbds::tree<T, __gnu_pbds::null_type, std::less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>; template <class S, class T> using hash_table = __gnu_pbds::gp_hash_table<S, T>; #endif #ifdef LOCAL_DEBUG #if (defined USE_EXTERNAL_CONTAINERS) || (defined NO_PRINT_INF) || (defined PROPER) #include <../src/debugger.hpp> #else #include <debugger.hpp> #endif #endif // #define PROPER #if (defined __INTELLISENSE__) && (!defined PROPER) #define NDEBUG namespace std { #endif #include <cassert> #include <cctype> #include <cmath> #include <cstddef> #include <cstdint> #include <cstdio> #include <cstdlib> #include <algorithm> #include <array> #include <bitset> #include <complex> #include <deque> #include <functional> #include <iostream> #include <iomanip> #include <iterator> #include <limits> #include <list> #include <map> #include <numeric> #include <queue> #include <regex> #include <set> #include <sstream> #include <stack> #include <string> #include <string_view> #include <tuple> #include <typeinfo> #include <type_traits> #include <utility> #include <vector> #if (defined __INTELLISENSE__) && (!defined PROPER) using namespace std; } #endif #ifdef LOCAL_DEBUG #define STR(x) #x #define STRINGIFY(x) STR(x) #define FILE_LINE "[Debug] ./" __FILE__ ":" STRINGIFY(__LINE__) #define see(...) debugger::multi_print(#__VA_ARGS__, __VA_ARGS__) #define see2(arg) arg.debug_print(#arg) #define here(...) debugger::os << FILE_LINE << " in " << __func__ << ": \e[32mReached\e[39m\n" #define com(msg) debugger::os << FILE_LINE << " in " << __func__ << ":\n \e[36mComment:\e[39m " << msg << "\n" #define err(msg) debugger::os << FILE_LINE << " in " << __func__ << ":\n \e[31mError:\e[39m " << msg << "\n" #define local(...) do { __VA_ARGS__ } while (0) #define alter(x, y) x #else #define see(...) (static_cast<void>(0)) #define see2(arg) (static_cast<void>(0)) #define here(...) (static_cast<void>(0)) #define com(msg) (static_cast<void>(0)) #define err(msg) (static_cast<void>(0)) #define local(...) (static_cast<void>(0)) #define alter(x, y) y #endif #if (defined LOCAL_DEBUG) && (!defined NOWARN) #define warn(msg) debugger::os << FILE_LINE << " in " << __func__ << ":\n \e[33mWarning:\e[39m " << msg << "\n" #else #define warn(msg) (static_cast<void>(0)) #endif #if (defined LOCAL_DEBUG) || (defined LOCAL_NDEBUG) || (defined __INTELLISENSE__) #define NOEXCEPT #define M_assert(expr) assert(expr) #define O_assert(expr) assert(expr) #else #define NOEXCEPT noexcept #define M_assert(expr) do {if(__builtin_expect(!(expr), 0)) {auto p = static_cast<std::int64_t*>(std::malloc(1 << 30)); for (int i = 0; i < (1 << 27); p[i] = 1, i += (1 << 9)); std::cerr << (*p);}} while (0) #define O_assert(expr) do {if(__builtin_expect(!(expr), 0)) {const auto X = std::string(1000, '-'); for(int i = 0; i < (1 << 18); i++) std::cout << X;}} while (0) #endif #define as(type, val) static_cast<std::decay_t<type>>(val) #define INDIRECT(...) __VA_ARGS__ #define rep(loop_var, loop_end) \ for ( \ auto loop_var = as(std::make_signed_t<decltype(loop_end)>, 0); \ loop_var < as(decltype(loop_var), loop_end); \ ++loop_var \ ) #define rng(loop_var, loop_start, loop_end, loop_increment) \ for ( \ auto loop_var = as(INDIRECT(std::make_signed_t<std::common_type_t<decltype(loop_start), decltype(loop_end)>>), loop_start); \ ((loop_increment) > 0) ? (loop_var < as(decltype(loop_var), loop_end)) : (loop_var > as(decltype(loop_var), loop_end)); \ loop_var += (loop_increment) \ ) #define erng(loop_var, loop_start, loop_end, loop_increment) \ for ( \ auto loop_var = as(INDIRECT(std::make_signed_t<std::common_type_t<decltype(loop_start), decltype(loop_end)>>), loop_start); \ ((loop_increment) > 0) ? (loop_var <= as(decltype(loop_var), loop_end)) : (loop_var >= as(decltype(loop_var), loop_end)); \ loop_var += (loop_increment) \ ) [[maybe_unused]] constexpr int INF = 1000000005; [[maybe_unused]] constexpr long long LINF = 1000000000000000005LL; [[maybe_unused]] constexpr double EPS = 1e-9; [[maybe_unused]] constexpr long double LEPS = 1e-14L; [[maybe_unused]] constexpr int dy[9] = {1, 0, -1, 0, 1, 1, -1, -1, 0}; [[maybe_unused]] constexpr int dx[9] = {0, 1, 0, -1, -1, 1, 1, -1, 0}; template <class... Ts> constexpr auto Min(const Ts... args) { return std::min({ as(std::common_type_t<Ts...>, args) ... }); } template <class... Ts> constexpr auto Max(const Ts... args) { return std::max({ as(std::common_type_t<Ts...>, args) ... }); } // clang-format on #pragma endregion #pragma region lib_static_modint #define lib_mint 1 #define lib_static_modint 1 namespace lib { template <std::int_least32_t modulo> class static_modint { std::int_least32_t value; template <class Tp> static constexpr std::int_least32_t calc_inverse(Tp n) noexcept { Tp b = modulo, u = 1, v = 0, t; while (b > 0) { t = n / b; // std::swap is not necessarily constexpr in C++17 // std::swap(n -= t * b, b); Tp tmp = std::move(n -= t * b); n = std::move(b); b = std::move(tmp); // std::swap(u -= t * v, v); tmp = std::move(u -= t * v); u = std::move(v); v = std::move(tmp); } if (u < 0) u += modulo; return static_cast<std::int_least32_t>(u); } template <class Tp> static constexpr std::int_least32_t clamp_ll(Tp v) noexcept { if (modulo <= v || v < -modulo) v %= modulo; if (v < 0) v += modulo; return static_cast<std::int_least32_t>(v); } constexpr void clamp_self(void) noexcept { if (0 <= value) { if (value < modulo) return; if (value < modulo * 2) value -= modulo; else value -= modulo * 2; } else { if (-modulo < value) value += modulo; else if (-modulo * 2 < value) value += modulo * 2; else { value += modulo; value += modulo * 2; } } } public: using type = std::int_least32_t; static constexpr type mod(void) noexcept { return modulo; } // constructor constexpr static_modint(void) noexcept : value(0) {} template <class ValueType> constexpr static_modint(const ValueType v) noexcept { if constexpr (std::is_integral_v<ValueType> && (std::numeric_limits<ValueType>::digits <= 32)) { value = v; clamp_self(); } else { value = clamp_ll(v); } } constexpr static_modint(const std::int_least32_t v, bool) noexcept : value(v) {} // operator constexpr static_modint<modulo> operator+(const static_modint<modulo> rhs) const noexcept { return static_modint<modulo>(value + rhs.value); } constexpr static_modint<modulo> operator-(const static_modint<modulo> rhs) const noexcept { return static_modint<modulo>(value - rhs.value); } constexpr static_modint<modulo> operator*(const static_modint<modulo> rhs) const noexcept { return static_modint<modulo>(static_cast<std::int_least64_t>(value) * rhs.value); } constexpr static_modint<modulo> operator/(const static_modint<modulo> rhs) const NOEXCEPT { // O_assert(rhs.value != 0); return static_modint<modulo>(static_cast<std::int_least64_t>(value) * calc_inverse(rhs.value)); } constexpr static_modint<modulo> operator%(const static_modint<modulo> rhs) const NOEXCEPT { warn("operator% <static_modint, static_modint> : Are you sure you want to do this?"); // O_assert(rhs.value != 0); return static_modint<modulo>(value % rhs.value, true); } constexpr static_modint<modulo> operator&(const static_modint<modulo> rhs) const noexcept { warn("operator& <static_modint, static_modint> : Are you sure you want to do this?"); return static_modint<modulo>(value & rhs.value, true); } constexpr static_modint<modulo> operator|(const static_modint<modulo> rhs) const noexcept { warn("operator| <static_modint, static_modint> : Are you sure you want to do this?"); return static_modint<modulo>(value | rhs.value); } constexpr static_modint<modulo> operator^(const static_modint<modulo> rhs) const noexcept { warn("operator^ <static_modint, static_modint> : Are you sure you want to do this?"); return static_modint<modulo>(value ^ rhs.value); } constexpr static_modint<modulo> operator<<(const static_modint<modulo> rhs) const noexcept { warn("operator<< <static_modint, static_modint> : Are you sure you want to do this?"); return static_modint<modulo>(static_cast<std::int_least64_t>(value) << rhs.value); } constexpr static_modint<modulo> operator>>(const static_modint<modulo> rhs) const noexcept { warn("operator>> <static_modint, static_modint> : Are you sure you want to do this?"); return static_modint<modulo>(value >> rhs.value, true); } constexpr static_modint<modulo>& operator+=(const static_modint<modulo> rhs) noexcept { value += rhs.value; if (value >= modulo) value -= modulo; return *this; } constexpr static_modint<modulo>& operator-=(const static_modint<modulo> rhs) noexcept { value -= rhs.value; if (value < 0) value += modulo; return *this; } constexpr static_modint<modulo>& operator*=(const static_modint<modulo> rhs) noexcept { value = clamp_ll(static_cast<std::int_least64_t>(value) * rhs.value); return *this; } constexpr static_modint<modulo>& operator/=(const static_modint<modulo> rhs) NOEXCEPT { // O_assert(rhs != 0); value = clamp_ll(static_cast<std::int_least64_t>(value) * calc_inverse(rhs.value)); return *this; } constexpr static_modint<modulo>& operator%=(const static_modint<modulo> rhs) NOEXCEPT { warn("operator%= <static_modint, static_modint> : Are you sure you want to do this?"); // O_assert(rhs != 0); value %= rhs.value; if (value < 0) value += modulo; return *this; } constexpr static_modint<modulo>& operator&=(const static_modint<modulo> rhs) noexcept { warn("operator&= <static_modint, static_modint> : Are you sure you want to do this?"); value &= rhs.value; return *this; } constexpr static_modint<modulo>& operator|=(const static_modint<modulo> rhs) noexcept { warn("operator|= <static_modint, static_modint> : Are you sure you want to do this?"); value |= rhs.value; clamp_self(); return *this; } constexpr static_modint<modulo>& operator^=(const static_modint<modulo> rhs) noexcept { warn("operator^= <static_modint, static_modint> : Are you sure you want to do this?"); value ^= rhs.value; clamp_self(); return *this; } constexpr static_modint<modulo>& operator<<=(const static_modint<modulo> rhs) noexcept { warn("operator<<= <static_modint, static_modint> : Are you sure you want to do this?"); value = clamp_ll(static_cast<std::int_least64_t>(value) << rhs.value); return *this; } constexpr static_modint<modulo>& operator>>=(const static_modint<modulo> rhs) noexcept { warn("operator>>= <static_modint, static_modint> : Are you sure you want to do this?"); value >>= rhs.value; return *this; } template <class RhsType> constexpr static_modint<modulo> operator+(const RhsType rhs) const noexcept { return static_modint<modulo>(value + clamp_ll(rhs)); } template <class RhsType> constexpr static_modint<modulo> operator-(const RhsType rhs) const noexcept { return static_modint<modulo>(value - clamp_ll(rhs)); } template <class RhsType> constexpr static_modint<modulo> operator*(const RhsType rhs) const noexcept { return static_modint<modulo>(static_cast<std::int_least64_t>(value) * clamp_ll(rhs)); } template <class RhsType> constexpr static_modint<modulo> operator/(const RhsType rhs) const NOEXCEPT { // O_assert(rhs != 0); std::int_least64_t mul = (rhs > 0) ? calc_inverse(rhs) : -calc_inverse(-rhs); return static_modint<modulo>(value * mul); } template <class RhsType> constexpr static_modint<modulo> operator%(const RhsType rhs) const NOEXCEPT { warn("operator% <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); // O_assert(rhs != 0); return static_modint<modulo>(value % rhs, true); } template <class RhsType> constexpr static_modint<modulo> operator&(const RhsType rhs) const noexcept { warn("operator& <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); return static_modint<modulo>(value & rhs, true); } template <class RhsType> constexpr static_modint<modulo> operator|(const RhsType rhs) const noexcept { warn("operator| <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); return static_modint<modulo>(value | rhs); } template <class RhsType> constexpr static_modint<modulo> operator^(const RhsType rhs) const noexcept { warn("operator^ <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); return static_modint<modulo>(value ^ rhs); } template <class RhsType> constexpr static_modint<modulo> operator<<(const RhsType rhs) const noexcept { warn("operator<< <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); return static_modint<modulo>(static_cast<std::int_least64_t>(value) << rhs); } template <class RhsType> constexpr static_modint<modulo> operator>>(const RhsType rhs) const noexcept { warn("operator>> <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); return static_modint<modulo>(value >> rhs, true); } template <class RhsType> constexpr static_modint<modulo>& operator+=(const RhsType rhs) noexcept { value = clamp_ll(static_cast<std::int_least64_t>(value) + rhs); return *this; } template <class RhsType> constexpr static_modint<modulo>& operator-=(const RhsType rhs) noexcept { value = clamp_ll(static_cast<std::int_least64_t>(value) - rhs); return *this; } template <class RhsType> constexpr static_modint<modulo>& operator*=(const RhsType rhs) noexcept { value = clamp_ll(static_cast<std::int_least64_t>(value) * clamp_ll(rhs)); return *this; } template <class RhsType> constexpr static_modint<modulo>& operator/=(const RhsType rhs) NOEXCEPT { // O_assert(rhs != 0); std::int_least64_t mul = (rhs > 0) ? calc_inverse(rhs) : -calc_inverse(-rhs); value = clamp_ll(value * mul); return *this; } template <class RhsType> constexpr static_modint<modulo>& operator%=(const RhsType rhs) NOEXCEPT { warn("operator%= <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); // O_assert(rhs != 0); value %= rhs; return *this; } template <class RhsType> constexpr static_modint<modulo>& operator&=(const RhsType rhs) noexcept { warn("operator&= <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); value &= rhs; return *this; } template <class RhsType> constexpr static_modint<modulo>& operator|=(const RhsType rhs) noexcept { warn("operator|= <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); value |= rhs; clamp_self(); return *this; } template <class RhsType> constexpr static_modint<modulo>& operator^=(const RhsType rhs) noexcept { warn("operator^= <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); value ^= rhs; clamp_self(); return *this; } template <class RhsType> constexpr static_modint<modulo>& operator<<=(const RhsType rhs) noexcept { warn("operator<<= <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); value = clamp_ll(static_cast<std::int_least64_t>(value) << rhs); return *this; } template <class RhsType> constexpr static_modint<modulo>& operator>>=(const RhsType rhs) noexcept { warn("operator>>= <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); value >>= rhs; return *this; } constexpr bool operator!(void) const noexcept { warn("operator! <static_modint> : Are you sure you want to do this?"); return value == 0; } constexpr static_modint<modulo> operator~(void) const noexcept { warn("operator~ <static_modint> : Are you sure you want to do this?"); return static_modint<modulo>(~value); } constexpr static_modint<modulo> operator-(void) const noexcept { return static_modint<modulo>(value == 0 ? 0 : modulo - value, true); } constexpr static_modint<modulo>& operator+(void) const noexcept { return *this; } constexpr static_modint<modulo>& operator++(void) noexcept { value = ((value + 1 == modulo) ? 0 : value + 1); return *this; } constexpr static_modint<modulo>& operator--(void) noexcept { value = ((value == 0) ? modulo - 1 : value - 1); return *this; } constexpr static_modint<modulo> operator++(int) noexcept { std::int_least32_t ret = value; ++(*this); return static_modint<modulo>(ret, true); } constexpr static_modint<modulo> operator--(int) noexcept { std::int_least32_t ret = value; --(*this); return static_modint<modulo>(ret, true); } constexpr bool operator==(const static_modint<modulo> rhs) const noexcept { return value == rhs.value; } constexpr bool operator!=(const static_modint<modulo> rhs) const noexcept { return value != rhs.value; } constexpr bool operator<(const static_modint<modulo> rhs) const noexcept { warn("operator< <static_modint, static_modint> : Are you sure you want to do this?"); return value < rhs.value; } constexpr bool operator<=(const static_modint<modulo> rhs) const noexcept { warn("operator<= <static_modint, static_modint> : Are you sure you want to do this?"); return value <= rhs.value; } constexpr bool operator>(const static_modint<modulo> rhs) const noexcept { warn("operator> <static_modint, static_modint> : Are you sure you want to do this?"); return value > rhs.value; } constexpr bool operator>=(const static_modint<modulo> rhs) const noexcept { warn("operator>= <static_modint, static_modint> : Are you sure you want to do this?"); return value >= rhs.value; } template <class RhsType> constexpr bool operator==(const RhsType rhs) const noexcept { return value == rhs; } template <class RhsType> constexpr bool operator!=(const RhsType rhs) const noexcept { return value != rhs; } template <class RhsType> constexpr bool operator<(const RhsType rhs) const noexcept { warn("operator< <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); return value < rhs; } template <class RhsType> constexpr bool operator<=(const RhsType rhs) const noexcept { warn("operator<= <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); return value <= rhs; } template <class RhsType> constexpr bool operator>(const RhsType rhs) const noexcept { warn("operator> <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); return value > rhs; } template <class RhsType> constexpr bool operator>=(const RhsType rhs) const noexcept { warn("operator>= <static_modint, " << debugger::type_name<RhsType> << "> : Are you sure you want to do this?"); return value >= rhs; } constexpr operator std::int_least32_t() const noexcept { return value; } friend std::istream& operator>>(std::istream& is, static_modint<modulo>& rhs) { std::int_least64_t tmp; is >> tmp; if (tmp < -modulo || modulo <= tmp) tmp %= modulo; if (tmp < 0) tmp += modulo; rhs.value = static_cast<std::int_least32_t>(tmp); return is; } friend std::ostream& operator<<(std::ostream& os, static_modint<modulo>& rhs) { return os << rhs.value; } // functions constexpr static_modint<modulo> inv(void) const NOEXCEPT { // O_assert(value != 0); return static_modint<modulo>(calc_inverse(value), true); } template <bool index_positive_guaranteed = true, class Tp = std::int_least32_t> constexpr static_modint<modulo> pow(Tp index) const noexcept { if constexpr (!index_positive_guaranteed) { // O_assert(value != 0 || index > 0); if (value == 0) return static_modint<modulo>(0, true); if (index == 0) return static_modint<modulo>(1, true); if (index < 0) return static_modint<modulo>(value, true).inv().pow<true>(-index); } static_modint<modulo> ret(1, true), base(value, true); while (index > 0) { if (index & 1) ret *= base; base *= base; index >>= 1; } return ret; } constexpr std::pair<std::int_least32_t, std::int_least32_t> to_frac(void) const noexcept { std::int_least32_t x = modulo - value, y = value, u = 1, v = 1; std::pair<std::int_least32_t, std::int_least32_t> ret {value, 1}; std::int_least32_t num = value, den = 1; std::int_least32_t cost = num + den; while (x > 0) { if (x <= num) { std::int_least32_t q = num / x; num = num % x; den += q * u; if (num == 0) break; if (num + den < cost) { cost = num + den; ret.first = num; ret.second = den; } } std::int_least32_t q = y / x; y = y % x; v += q * u; q = x / y; x = x % y; u += q * v; } return ret; } }; template <class LhsType, std::int_least32_t modulo> constexpr static_modint<modulo> operator+(const LhsType lhs, const static_modint<modulo> rhs) noexcept { return rhs + lhs; } template <class LhsType, std::int_least32_t modulo> constexpr static_modint<modulo> operator-(const LhsType lhs, const static_modint<modulo> rhs) noexcept { return -rhs + lhs; } template <class LhsType, std::int_least32_t modulo> constexpr static_modint<modulo> operator*(const LhsType lhs, const static_modint<modulo> rhs) noexcept { return rhs * lhs; } template <class LhsType, std::int_least32_t modulo> constexpr static_modint<modulo> operator/(const LhsType lhs, const static_modint<modulo> rhs) noexcept { return rhs.inv() * lhs; } template <class LhsType, std::int_least32_t modulo> constexpr static_modint<modulo> operator%(const LhsType lhs, const static_modint<modulo> rhs) noexcept { warn("operator% <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return static_modint<modulo>(lhs % static_cast<std::int_least32_t>(rhs), true); } template <class LhsType, std::int_least32_t modulo, std::enable_if_t<std::is_integral_v<LhsType>, std::nullptr_t> = nullptr> constexpr static_modint<modulo> operator<<(const LhsType lhs, const static_modint<modulo> rhs) noexcept { warn("operator<< <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return static_modint<modulo>(static_cast<std::int_least64_t>(lhs) << static_cast<std::int_least32_t>(rhs)); } template <class LhsType, std::int_least32_t modulo, std::enable_if_t<std::is_integral_v<LhsType>, std::nullptr_t> = nullptr> constexpr static_modint<modulo> operator>>(const LhsType lhs, const static_modint<modulo> rhs) noexcept { warn("operator>> <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return static_modint<modulo>(lhs >> static_cast<std::int_least32_t>(rhs)); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator+=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { return lhs += static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator-=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { return lhs -= static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator*=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { return lhs *= static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator/=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { return lhs /= static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator%=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { warn("operator%= <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs %= static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator&=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { warn("operator&= <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs &= static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator|=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { warn("operator|= <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs |= static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator^=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { warn("operator^= <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs ^= static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator<<=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { warn("operator<<= <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs <<= static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr LhsType& operator>>=(LhsType& lhs, const static_modint<modulo> rhs) noexcept { warn("operator>>= <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs >>= static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr bool operator<(const LhsType lhs, const static_modint<modulo> rhs) noexcept { warn("operator< <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs < static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr bool operator<=(const LhsType lhs, const static_modint<modulo> rhs) noexcept { warn("operator<= <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs < static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr bool operator>(const LhsType lhs, const static_modint<modulo> rhs) noexcept { warn("operator> <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs < static_cast<std::int_least32_t>(rhs); } template <class LhsType, std::int_least32_t modulo> constexpr bool operator>=(const LhsType lhs, const static_modint<modulo> rhs) noexcept { warn("operator>= <" << debugger::type_name<LhsType> << ", static_modint> : Are you sure you want to do this?"); return lhs < static_cast<std::int_least32_t>(rhs); } } // namespace lib #pragma endregion using mint = lib::static_modint<998244353>; void solve() { long long N, M; std::cin >> N >> M; mint ans = 0, s = 0; std::vector<mint> l(M + 1), m(M + 2); erng(i, 1, M, 1) { s += i; mint p = mint(i).pow(N - 1); l[i] = (p * N) * s; m[M - i + 1] = (mint(i).pow(N) * N) * (M + 1) - l[i]; } // see(l, m); erng(i, 1, M, 1) { mint tmp = i * (l[i] - l[i - 1]); ans += tmp; // see(i, tmp); } erng(i, M, 1, -1) { mint tmp = i * (m[i] - m[i + 1]); ans -= tmp; // see(i, tmp); } std::cout << ans << "\n"; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); solve(); }