結果

問題 No.2503 Typical Path Counting Problem on a Grid
ユーザー baluteshihbaluteshih
提出日時 2023-10-13 23:39:28
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 231 ms / 2,000 ms
コード長 2,791 bytes
コンパイル時間 2,062 ms
コンパイル使用メモリ 200,148 KB
実行使用メモリ 120,728 KB
最終ジャッジ日時 2023-10-13 23:39:33
合計ジャッジ時間 4,841 ms
ジャッジサーバーID
(参考情報)
judge14 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 146 ms
120,620 KB
testcase_01 AC 156 ms
120,652 KB
testcase_02 AC 156 ms
120,728 KB
testcase_03 AC 175 ms
120,592 KB
testcase_04 AC 200 ms
120,520 KB
testcase_05 AC 171 ms
120,568 KB
testcase_06 AC 206 ms
120,564 KB
testcase_07 AC 231 ms
120,672 KB
testcase_08 AC 192 ms
120,572 KB
testcase_09 AC 202 ms
120,624 KB
権限があれば一括ダウンロードができます

ソースコード

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();
    }
}
0