結果
| 問題 |
No.2529 Treasure Hunter
|
| コンテスト | |
| ユーザー |
siganai
|
| 提出日時 | 2023-11-03 22:28:39 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 4 ms / 2,000 ms |
| コード長 | 11,002 bytes |
| コンパイル時間 | 3,040 ms |
| コンパイル使用メモリ | 226,236 KB |
| 最終ジャッジ日時 | 2025-02-17 18:32:49 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 22 |
ソースコード
#line 1 "main.cpp"
#pragma GCC target("avx,avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#ifdef LOCAL
#include <debug.hpp>
#define debug(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (static_cast<void>(0))
#endif
using namespace std;
using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vvvl = vector<vvl>;
using vpii = vector<pii>;
using vpll = vector<pll>;
using vs = vector<string>;
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;
#define overload4(_1, _2, _3, _4, name, ...) name
#define overload3(a,b,c,name,...) name
#define rep1(n) for (ll UNUSED_NUMBER = 0; UNUSED_NUMBER < (n); ++UNUSED_NUMBER)
#define rep2(i, n) for (ll i = 0; i < (n); ++i)
#define rep3(i, a, b) for (ll i = (a); i < (b); ++i)
#define rep4(i, a, b, c) for (ll i = (a); i < (b); i += (c))
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define rrep1(n) for(ll i = (n) - 1;i >= 0;i--)
#define rrep2(i,n) for(ll i = (n) - 1;i >= 0;i--)
#define rrep3(i,a,b) for(ll i = (b) - 1;i >= (a);i--)
#define rrep4(i,a,b,c) for(ll i = (a) + ((b)-(a)-1) / (c) * (c);i >= (a);i -= c)
#define rrep(...) overload4(__VA_ARGS__, rrep4, rrep3, rrep2, rrep1)(__VA_ARGS__)
#define all1(i) begin(i) , end(i)
#define all2(i,a) begin(i) , begin(i) + a
#define all3(i,a,b) begin(i) + a , begin(i) + b
#define all(...) overload3(__VA_ARGS__, all3, all2, all1)(__VA_ARGS__)
#define sum(...) accumulate(all(__VA_ARGS__),0LL)
template<class T> bool chmin(T &a, const T &b){ if(a > b){ a = b; return 1; } else return 0; }
template<class T> bool chmax(T &a, const T &b){ if(a < b){ a = b; return 1; } else return 0; }
template<class T> auto min(const T& a){return *min_element(all(a));}
template<class T> auto max(const T& a){return *max_element(all(a));}
template<class... Ts> void in(Ts&... t);
#define INT(...) int __VA_ARGS__; in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__; in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__; in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; in(__VA_ARGS__)
#define VEC(type, name, size) vector<type> name(size); in(name)
#define VV(type, name, h, w) vector<vector<type>> name(h, vector<type>(w)); in(name)
ll intpow(ll a, ll b){ ll ans = 1; while(b){if(b & 1) ans *= a; a *= a; b /= 2;} return ans;}
ll modpow(ll a, ll b, ll p){ ll ans = 1; a %= p;if(a < 0) a += p;while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
ll GCD(ll a,ll b) { if(a == 0 || b == 0) return 0; if(a % b == 0) return b; else return GCD(b,a%b);}
ll LCM(ll a,ll b) { if(a == 0) return b; if(b == 0) return a;return a / GCD(a,b) * b;}
void Yes() {cout << "Yes\n";return;}
void No() {cout << "No\n";return;}
void YES() {cout << "YES\n";return;}
void NO() {cout << "NO\n";return;}
namespace IO{
#define VOID(a) decltype(void(a))
struct setting{ setting(){cin.tie(nullptr); ios::sync_with_stdio(false);fixed(cout); cout.precision(12);}} setting;
template<int I> struct P : P<I-1>{};
template<> struct P<0>{};
template<class T> void i(T& t){ i(t, P<3>{}); }
void i(vector<bool>::reference t, P<3>){ int a; i(a); t = a; }
template<class T> auto i(T& t, P<2>) -> VOID(cin >> t){ cin >> t; }
template<class T> auto i(T& t, P<1>) -> VOID(begin(t)){ for(auto&& x : t) i(x); }
template<class T, size_t... idx> void ituple(T& t, index_sequence<idx...>){in(get<idx>(t)...);}
template<class T> auto i(T& t, P<0>) -> VOID(tuple_size<T>{}){ituple(t, make_index_sequence<tuple_size<T>::value>{});}
#undef VOID
}
#define unpack(a) (void)initializer_list<int>{(a, 0)...}
template<class... Ts> void in(Ts&... t){ unpack(IO :: i(t)); }
#undef unpack
static const double PI = 3.1415926535897932;
template <class F> struct REC {
F f;
REC(F &&f_) : f(forward<F>(f_)) {}
template <class... Args> auto operator()(Args &&...args) const { return f(*this, forward<Args>(args)...); }};
constexpr int mod = 998244353;
//constexpr int mod = 1000000007;
#line 2 "library/modint/LazyMontgomeryModint.hpp"
template <uint32_t mod>
struct LazyMontgomeryModInt {
using mint = LazyMontgomeryModInt;
using i32 = int32_t;
using u32 = uint32_t;
using u64 = uint64_t;
static constexpr u32 get_r() {
u32 ret = mod;
for (i32 i = 0; i < 4; ++i) ret *= 2 - mod * ret;
return ret;
}
static constexpr u32 r = get_r();
static constexpr u32 n2 = -u64(mod) % mod;
static_assert(r * mod == 1);
static_assert(mod < (1 << 30));
static_assert((mod & 1) == 1);
u32 a;
constexpr LazyMontgomeryModInt() : a(0) {}
constexpr LazyMontgomeryModInt(const int64_t &b)
: a(reduce(u64(b % mod + mod) * n2)){};
static constexpr u32 reduce(const u64 &b) {
return (b + u64(u32(b) * u32(-r)) * mod) >> 32;
}
constexpr mint &operator+=(const mint &b) {
if (i32(a += b.a - 2 * mod) < 0) a += 2 * mod;
return *this;
}
constexpr mint &operator-=(const mint &b) {
if (i32(a -= b.a) < 0) a += 2 * mod;
return *this;
}
constexpr mint &operator*=(const mint &b) {
a = reduce(u64(a) * b.a);
return *this;
}
constexpr mint &operator/=(const mint &b) {
*this *= b.inverse();
return *this;
}
constexpr mint operator+(const mint &b) const { return mint(*this) += b; }
constexpr mint operator-(const mint &b) const { return mint(*this) -= b; }
constexpr mint operator*(const mint &b) const { return mint(*this) *= b; }
constexpr mint operator/(const mint &b) const { return mint(*this) /= b; }
constexpr bool operator==(const mint &b) const {
return (a >= mod ? a - mod : a) == (b.a >= mod ? b.a - mod : b.a);
}
constexpr bool operator!=(const mint &b) const {
return (a >= mod ? a - mod : a) != (b.a >= mod ? b.a - mod : b.a);
}
constexpr mint operator-() const { return mint() - mint(*this); }
constexpr mint pow(u64 n) const {
mint ret(1), mul(*this);
while (n > 0) {
if (n & 1) ret *= mul;
mul *= mul;
n >>= 1;
}
return ret;
}
constexpr mint inverse() const { return pow(mod - 2); }
friend ostream &operator<<(ostream &os, const mint &b) {
return os << b.get();
}
friend istream &operator>>(istream &is, mint &b) {
int64_t t;
is >> t;
b = LazyMontgomeryModInt<mod>(t);
return (is);
}
constexpr u32 get() const {
u32 ret = reduce(a);
return ret >= mod ? ret - mod : ret;
}
static constexpr u32 get_mod() { return mod; }
};
#line 90 "main.cpp"
using mint = LazyMontgomeryModInt<mod>;
#line 2 "library/matrix/matrix-array.hpp"
template<typename T,int H,int W>
struct Matrix {
using Array = array<array<T,W>,H>;
Array A;
Matrix():A() {
for(int i = 0;i < H;i++) {
for(int j = 0;j < W;j++) {
(*this)[i][j] = T();
}
}
}
int height() const {return H;}
int width() const {return W;}
inline const array<T,W> &operator[](int k) const {return A[k];}
inline array<T,W> &operator[](int k){return A[k];}
static Matrix I() {
assert(H == W);
Matrix mat;
for(int i = 0;i < H;i++) mat[i][i] = 1;
return (mat);
}
Matrix &operator+=(const Matrix &B) {
for(int i = 0;i < H;i++) {
for(int j = 0;j < W;j++) {
A[i][j] += B[i][j];
}
}
return (*this);
}
Matrix &operator-=(const Matrix &B) {
for(int i = 0;i < H;i++) {
for(int j = 0;j < W;j++) {
A[i][j] -= B[i][j];
}
}
return (*this);
}
Matrix &operator*=(const Matrix &B) {
assert(H == W);
Matrix C;
for(int i = 0;i < H;i++) {
for(int k = 0;k < H;k++) {
for(int j = 0;j < H;j++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
A.swap(C.A);
return (*this);
}
Matrix &operator^=(long long k) {
Matrix B = Matrix::I();
while(k > 0) {
if(k & 1) B *= *this;
*this *= *this;
k >>= 1LL;
}
A.swap(B.A);
return (*this);
}
Matrix operator+(const Matrix &B) const{return (Matrix(*this) += B);}
Matrix operator-(const Matrix &B) const{return (Matrix(*this) -= B);}
Matrix operator*(const Matrix &B) const{return (Matrix(*this) *= B);}
Matrix operator^(const long long k) const{return (Matrix(*this) ^= k);}
bool operator==(const Matrix &B) const {
for(int i = 0;i < H;i++) {
for(int j = 0;j < W;j++) {
if(A[i][j] != B[i][j]) return false;
}
}
return true;
}
bool operator!=(const Matrix &B) const {
for(int i = 0;i < H;i++) {
for(int j = 0;j < W;j++) {
if(A[i][j] != B[i][j]) return true;
}
}
return false;
}
friend ostream &operator<<(ostream &os,const Matrix &p) {
for(int i = 0;i < H;i++) {
os << "[";
for(int j = 0;j < W;j++) {
os << p[i][j] << (j+1 == W ?"]\n":",");
}
}
return(os);
}
T determinant(int n = -1) {
if(n == -1) n = H;
Matrix B(*this);
T ret = 1;
for(int i = 0;i < n;i++) {
int idx = -1;
for(int j = i;j < n;j++) {
if(B[j][i] != 0) {
idx = j;
break;
}
}
if(idx == -1) return 0;
if(i != idx) {
ret *= T(-1);
swap(B[i],B[idx]);
}
ret *= B[i][i];
T inv = T(1) / B[i][i];
for(int j = 0;j < n;j++) {
B[i][j] *= inv;
}
for(int j = i+1;j < n;j++) {
T a = B[j][i];
if(a == 0) continue;
for(int k = i;k < n;k++) {
B[j][k] -= B[i][k] * a;
}
}
}
return(ret);
}
};
#line 92 "main.cpp"
void solve() {
INT(m,n);
Matrix<mint,3,3> mat;
mat[0][0] = 1;
mat[0][1] = 1;
mat[0][2] = 1;
mat[1][0] = m;
mat[1][1] = m - 1;
mat[1][2] = m - 2;
if(m > 3) {
mat[2][0] = 1LL * m * (m - 1) / 2 - m;
mat[2][1] = 1LL * m * (m - 1) / 2 - m - max(0,(m - 3));
mat[2][2] = 1LL * m * (m - 1) / 2 - m - max(0,(m - 3)) * 2 + 1;
}
mat ^= n;
//debug(mat);
mint ans;
rep(i,3) ans += mat[i][0];
cout << ans << '\n';
}
int main() {
INT(TT);
while(TT--) solve();
}
siganai