結果

問題 No.2503 Typical Path Counting Problem on a Grid
ユーザー baluteshihbaluteshih
提出日時 2023-10-13 23:39:28
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 174 ms / 2,000 ms
コード長 2,791 bytes
コンパイル時間 1,800 ms
コンパイル使用メモリ 196,580 KB
最終ジャッジ日時 2025-02-17 07:37:03
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 10
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define X first
#define Y second
#define SZ(a) ((int)a.size())
#define ALL(v) v.begin(), v.end()
#define pb push_back
const int MOD = 998244353;
void add(int &x, int val) {
x += val;
if (x >= MOD) x -= MOD;
}
struct Matrix {
int n, m, M[2][2];
Matrix(int _n = 0, int _m = 0): n(_n), m(_m) {
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
M[i][j] = 0;
}
Matrix operator*(const Matrix &a) const {
Matrix res(n, a.m);
for (int i = 0; i < res.n; ++i)
for (int j = 0; j < res.m; ++j)
for (int k = 0; k < m; ++k)
add(res.M[i][j], (ll)M[i][k] * a.M[k][j] % MOD);
return res;
}
};
const int MAXN = 10000005;
int dp[MAXN + 5][2], tot[MAXN + 5];
void solve() {
ll n, m;
cin >> n >> m, ++n, ++m;
if (n > m) swap(n, m);
if (n == 1) {
cout << 1 << "\n";
return;
}
/*auto r = [&](ll idx) {
return min({idx + 1, n + m - 1 - idx, n});
};
for (int i = 0; i <= n + m - 2; ++i) {
sum[i][0] = sum[i][1] = 0;
int v = 0;
if (i == 0) v = 1;
if (i >= 1) add(v, sum[i - 1][0]);
if (i >= 2) add(v, sum[i - 2][1]);
if (i == n + m - 2) {
cout << v << "\n";
break;
}
add(sum[i][0], (ll)v * (r(i) - int(r(i) > r(i + 1))) % MOD);
add(sum[i][0], (ll)v * (r(i) - int(r(i) >= r(i + 1))) % MOD);
add(sum[i][1], (ll)v * (r(i) - int(r(i) >= r(i + 1)) - int(r(i) > r(i + 1))) % MOD);
}*/
Matrix base(1, 2);
// r(i - 1) < r(i): [0, n)
base.M[0][0] = tot[n];
base.M[0][1] = tot[n - 1];
// r(i - 1) == r(i): [n, m)
{
Matrix tr(2, 2);
tr.M[0][0] = 2 * n - 1;
tr.M[1][0] = n - 1;
tr.M[0][1] = 1;
for (ll x = m - n; x; x >>= 1, tr = tr * tr)
if (x & 1)
base = base * tr;
}
// r(i - 1) > r(i): [m, n+m-1)
int ans = 0;
add(ans, (ll)base.M[0][0] * (2 * n - 2) % MOD * tot[n - 1] % MOD);
add(ans, (ll)base.M[0][0] * (n - 2) % MOD * tot[n - 2] % MOD);
add(ans, (ll)base.M[0][1] * (n - 1) % MOD * tot[n - 1] % MOD);
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
for (int i = 1; i <= MAXN; ++i) {
dp[i][0] = dp[i][1] = 0;
tot[i] = 0;
if (i == 1) tot[i] = 1;
if (i > 1) add(tot[i], dp[i - 1][0]);
if (i > 2) add(tot[i], dp[i - 2][1]);
dp[i][0] = (ll)tot[i] * i * 2 % MOD;
dp[i][1] = (ll)tot[i] * i % MOD;
}
int t;
cin >> t;
while (t--) {
solve();
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0