結果

問題 No.2996 Floor Sum
コンテスト
ユーザー noya2
提出日時 2025-04-22 21:53:24
言語 C++23
(gcc 15.2.0 + boost 1.90.0)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
RE  
実行時間 -
コード長 29,763 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 5,612 ms
コンパイル使用メモリ 374,176 KB
実行使用メモリ 9,416 KB
最終ジャッジ日時 2026-07-10 04:05:09
合計ジャッジ時間 6,016 ms
ジャッジサーバーID
(参考情報)
judge3_0 / judge2_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1 RE * 1
other AC * 4 RE * 8
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#line 2 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"
using namespace std;

#include<bits/stdc++.h>
#line 1 "/Users/noya2/Desktop/Noya2_library/template/inout_old.hpp"
namespace noya2 {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
    os << p.first << " " << p.second;
    return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p){
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v){
    int s = (int)v.size();
    for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
    return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v){
    for (auto &x : v) is >> x;
    return is;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u){
    cin >> t;
    in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u){
    cout << t;
    if (sizeof...(u)) cout << sep;
    out(u...);
}

template<typename T>
void out(const vector<vector<T>> &vv){
    int s = (int)vv.size();
    for (int i = 0; i < s; i++) out(vv[i]);
}

struct IoSetup {
    IoSetup(){
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
        cerr << fixed << setprecision(7);
    }
} iosetup_noya2;

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/const.hpp"
namespace noya2{

const int iinf = 1'000'000'007;
const long long linf = 2'000'000'000'000'000'000LL;
const long long mod998 =  998244353;
const long long mod107 = 1000000007;
const long double pi = 3.14159265358979323;
const vector<int> dx = {0,1,0,-1,1,1,-1,-1};
const vector<int> dy = {1,0,-1,0,1,-1,-1,1};
const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string alp = "abcdefghijklmnopqrstuvwxyz";
const string NUM = "0123456789";

void yes(){ cout << "Yes\n"; }
void no(){ cout << "No\n"; }
void YES(){ cout << "YES\n"; }
void NO(){ cout << "NO\n"; }
void yn(bool t){ t ? yes() : no(); }
void YN(bool t){ t ? YES() : NO(); }

} // namespace noya2
#line 2 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp"

#line 6 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp"

namespace noya2{

unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){
    if (a == 0 || b == 0) return a + b;
    int n = __builtin_ctzll(a); a >>= n;
    int m = __builtin_ctzll(b); b >>= m;
    while (a != b) {
        int mm = __builtin_ctzll(a - b);
        bool f = a > b;
        unsigned long long c = f ? a : b;
        b = f ? b : a;
        a = (c - b) >> mm;
    }
    return a << std::min(n, m);
}

template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(std::abs(a),std::abs(b))); }

long long sqrt_fast(long long n) {
    if (n <= 0) return 0;
    long long x = sqrt(n);
    while ((x + 1) * (x + 1) <= n) x++;
    while (x * x > n) x--;
    return x;
}

template<typename T> T floor_div(const T n, const T d) {
    assert(d != 0);
    return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0);
}

template<typename T> T ceil_div(const T n, const T d) {
    assert(d != 0);
    return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0);
}

template<typename T> void uniq(std::vector<T> &v){
    std::sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
}

template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }

template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; }

} // namespace noya2
#line 8 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"

#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define repp(i,m,n) for (int i = (m); i < (int)(n); i++)
#define reb(i,n) for (int i = (int)(n-1); i >= 0; i--)
#define all(v) (v).begin(),(v).end()

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pil = pair<int,ll>;
using pli = pair<ll,int>;

namespace noya2{

/* ~ (. _________ . /) */

}

using namespace noya2;


#line 2 "c.cpp"

template<template<int p, int q> class func, int i, int j>
void process(auto ...args){
    func<i,j>()(args...);
}

template<template<int p, int q> class func, int i, int ...js>
void inner_loop(std::integer_sequence<int, js...>, auto ...args){
    (process<func, i, js>(args...), ...);
}

template<template<int p, int q> class func, int ijsumub, int ...is>
void inner_loop_loop(std::integer_sequence<int, is...>, auto ...args){
    (inner_loop<func, is>(std::make_integer_sequence<int, ijsumub-is>{}, args...), ...);
}

template<template<int p, int q> class func, int ijsumub>
void process_loop(auto ...args){
    inner_loop_loop<func, ijsumub>(std::make_integer_sequence<int, ijsumub>{}, args...);
}

namespace noya2::internal::floor_sum_loop_mod {

/*

for (int p = 0; p <= s; p++) for (int q = 0; q <= s-p; q++){
    for (int i = 0; i <= q; i++) for (int j = 0; j <= q-i; j++){
        ret[p][q] += fact(q) / (fact(i) * fact(j) * fact(q-i-j)) * pow(aquo, j) * pow(bquo, q-i-j) * rec[p+j][i];
    }
}

*/

template<template<int _p, int _q, int _i, int _j> class func, int p, int q, int i, int j>
void inner_process4(auto&& ...args){
    func<p,q,i,j>()(args...);
}

template<template<int _p, int _q, int _i, int _j> class func, int p, int q, int i, int ...js>
void inner_loop4(std::integer_sequence<int, js...>, auto&& ...args){
    (inner_process4<func, p, q, i, js>(args...), ...);
}

template<template<int _p, int _q, int _i, int _j> class func, int p, int q, int ...is>
void inner_looploop4(std::integer_sequence<int, is...>, auto&& ...args){
    (inner_loop4<func, p, q, is>(std::make_integer_sequence<int, q-is+1>{}, args...), ...);
}

template<template<int _p, int _q, int _i, int _j> class func, int p, int ...qs>
void inner_looplooploop4(std::integer_sequence<int, qs...>, auto&& ...args){
    (inner_looploop4<func, p, qs>(std::make_integer_sequence<int, qs+1>{}, args...), ...);
}

template<template<int _p, int _q, int _i, int _j> class func, int sumpq, int ...ps>
void inner_looplooplooploop4(std::integer_sequence<int, ps...>, auto&& ...args){
    (inner_looplooploop4<func, ps>(std::make_integer_sequence<int, sumpq-ps+1>{}, args...), ...);
}

template<template<int _p, int _q, int _i, int _j> class func, int sumpq>
void process_loop4(auto&& ...args){
    inner_looplooplooploop4<func, sumpq>(std::make_integer_sequence<int, sumpq+1>{}, args...);
}

} // namespace noya2::internal::floor_sum_loop_mod

namespace noya2::internal::floor_sum_loop_rec {

/*

for (int p = 0; p <= s; p++) for (int q = 0; q <= s-p; q++){
    ret[p][q] += pow(k, q) * power_sum<mint, p>(n);
    for (int i = 0; i <= q-1; i++) for (int j = 0; j <= p+1; j++){
        ret[p][q] -= binom(q, i) * coef(p, j) * rec[i][j];
    }
}

*/

template<template<int _p, int _q, int _i, int _j> class func, int p, int q, int i, int j>
void inner_process4(auto&& ...args){
    func<p,q,i,j>()(args...);
}

template<template<int _p, int _q, int _i, int _j> class func, int p, int q, int i, int ...js>
void inner_loop4(std::integer_sequence<int, js...>, auto&& ...args){
    (inner_process4<func, p, q, i, js>(args...), ...);
}

template<template<int _p, int _q, int _i, int _j> class func, int p, int q, int jub, int ...is>
void inner_looploop4(std::integer_sequence<int, is...>, auto&& ...args){
    (inner_loop4<func, p, q, is>(std::make_integer_sequence<int, jub>{}, args...), ...);
}

template<template<int _p, int _q, int _i, int _j> class func, int p, int ...qs>
void inner_looplooploop4(std::integer_sequence<int, qs...>, auto&& ...args){
    (func<p, qs, -1, -1>()(args...), ...);
    (inner_looploop4<func, p, qs, p+2>(std::make_integer_sequence<int, qs>{}, args...), ...);
}

template<template<int _p, int _q, int _i, int _j> class func, int sumpq, int ...ps>
void inner_looplooplooploop4(std::integer_sequence<int, ps...>, auto&& ...args){
    (inner_looplooploop4<func, ps>(std::make_integer_sequence<int, sumpq-ps+1>{}, args...), ...);
}

template<template<int _p, int _q, int _i, int _j> class func, int sumpq>
void process_loop4(auto&& ...args){
    inner_looplooplooploop4<func, sumpq>(std::make_integer_sequence<int, sumpq+1>{}, args...);
}

} // namespace noya2::internal::floor_sum_loop_rec

#line 2 "/Users/noya2/Desktop/Noya2_library/utility/modint.hpp"

#line 4 "/Users/noya2/Desktop/Noya2_library/utility/modint.hpp"

#line 2 "/Users/noya2/Desktop/Noya2_library/math/prime.hpp"

#line 4 "/Users/noya2/Desktop/Noya2_library/math/prime.hpp"
namespace noya2 {

constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime_flag = is_prime_constexpr(n);

// {gcd(a, b), a^{-1} mod b}
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;
    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u; 
        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root_flag = primitive_root_constexpr(m);

// constexpr long long primitive_root_constexpr(long long m){
//     if (m == (1LL << 47) - (1LL << 24) + 1) return 3;
//     return primitive_root_constexpr(static_cast<int>(m));
// }

} // namespace noya2
#line 6 "/Users/noya2/Desktop/Noya2_library/utility/modint.hpp"

namespace noya2{

struct barrett {
    unsigned int _m;
    unsigned long long im;
    explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}
    unsigned int umod() const { return _m; }
    unsigned int mul(unsigned int a, unsigned int b) const {
        unsigned long long z = a;
        z *= b;
        unsigned long long x = (unsigned long long)((__uint128_t(z) * im) >> 64);
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

template <int m>
struct static_modint {
    using mint = static_modint;
  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }
    constexpr static_modint() : _v(0) {}
    template<std::signed_integral T>
    constexpr static_modint(T v){
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template<std::unsigned_integral T>
    constexpr static_modint(T v){
        _v = (unsigned int)(v % umod());
    }
    constexpr unsigned int val() const { return _v; }
    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }
    constexpr mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    constexpr mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    constexpr mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    constexpr mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
    constexpr mint operator+() const { return *this; }
    constexpr mint operator-() const { return mint() - *this; }
    constexpr mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    constexpr mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }
    friend constexpr mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend constexpr mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend constexpr mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend constexpr mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend constexpr bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend constexpr bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }
    friend std::ostream &operator<<(std::ostream &os, const mint& p) {
        return os << p.val();
    }
    friend std::istream &operator>>(std::istream &is, mint &a) {
        long long t; is >> t;
        a = mint(t);
        return (is);
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = is_prime_flag<m>;
};


template <int id> struct dynamic_modint {
    using mint = dynamic_modint;
  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template<std::signed_integral T>
    dynamic_modint(T v){
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template<std::unsigned_integral T>
    dynamic_modint(T v){
        _v = (unsigned int)(v % umod());
    }
    unsigned int val() const { return _v; }
    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }
    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }
    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = noya2::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }
    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }
    friend std::ostream &operator<<(std::ostream &os, const mint& p) {
        return os << p.val();
    }
    friend std::istream &operator>>(std::istream &is, mint &a) {
        long long t; is >> t;
        a = mint(t);
        return (is);
    }

  private:
    unsigned int _v;
    static barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> noya2::barrett dynamic_modint<id>::bt(998244353);

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

template<typename T>
concept Modint = requires (T &a){
    T::mod();
    a.inv();
    a.val();
    a.pow(declval<int>());
};

} // namespace noya2
#line 114 "c.cpp"

namespace noya2::internal::floor_sum {

template<int e>
inline long long powint(long long x){
    return x * powint<e-1>(x);
}

template<>
inline long long powint<0>(long long){
    return 1;
}

template<std::signed_integral T, int e> constexpr long long factint = factint<T, e-1> * e;
template<std::signed_integral T> constexpr long long factint<T, 0> = 1;

template<Modint mint, int e> constexpr mint factmint = e * factmint<mint, e-1>;
template<Modint mint> constexpr mint factmint<mint, 0> = 1;
template<Modint mint, int e> constexpr mint ifactmint = factmint<mint, e>.inv();
template<Modint mint, int n, int r> constexpr mint binommint = factmint<mint, n> * ifactmint<mint, r> * ifactmint<mint, n-r>;
template<Modint mint, int n> constexpr mint invmint = factmint<mint, n-1> * ifactmint<mint, n>;


template<Modint mint, int n, int k> struct bernoulli_sum;
template<Modint mint, int n> constexpr mint bernoulli = -invmint<mint, n+1> * bernoulli_sum<mint, n, n>::value;
template<Modint mint> constexpr mint bernoulli<mint, 0> = 1;

template<Modint mint, int n, int k> struct bernoulli_sum {
    static constexpr mint value = binommint<mint, n+1, k-1> * bernoulli<mint, k-1> + bernoulli_sum<mint, n, k-1>::value;
};

template<Modint mint, int n> struct bernoulli_sum<mint, n, 0> {
    static constexpr mint value = 0;
};

template<Modint mint, int k, int ...js>
mint inner_power_sum(std::integer_sequence<int, js...>, mint n){
    mint ret = 0;
    ((ret += binommint<mint, k+1, js> * bernoulli<mint, js>, ret *= n), ...);
    return ret;
}

// sum[ i in [0, n) ] i^k
template<Modint mint, int k>
mint power_sum(mint n){
    return inner_power_sum<mint, k>(std::make_integer_sequence<int, k+1>{}, n) * invmint<mint, k+1>;
}

template<typename T, int k>
void sayar(const std::array<T, k> &a){
    vector<T> b(k);
    rep(i,k){
        b[i] = a[i];
    }
    out("ar",b);
}

template<Modint mint, int sumpq>
struct floor_sum_pq_info {
    using Int = long long;
    static constexpr int array_size = (sumpq+1)*(sumpq+2)/2;
    template<int i, int j> static constexpr int idx = (i <= sumpq/2 ? i*(sumpq+2)+j : (sumpq-i)*(sumpq+2)+sumpq+1-j);
    static constexpr int idx_func(int i, int j){
        return (i <= sumpq/2 ? i*(sumpq+2)+j : (sumpq-i)*(sumpq+2)+sumpq+1-j);
    }
    template<int q, int i, int j> static constexpr mint choose2 = factmint<mint, q> * ifactmint<mint, i> * ifactmint<mint, j> * ifactmint<mint, q-i-j>;
    template<int p, int j> static constexpr mint coef = bernoulli<mint, p-j+1> * binommint<mint, p+1, j> * invmint<mint, p+1>;
    template<int p> static constexpr mint coef<p, 0> = 0;

    template<int p, int q, int i, int j>
    struct inner_assign_mod {
        void operator()(std::array<mint, array_size> &rec,
                        std::array<mint, array_size> &ret,
                        mint aquo, mint bquo){
            std::get<idx<p,q>>(ret) += choose2<q, i, j> * aquo.pow(j) * bquo.pow(q-i-j) * std::get<idx<p+j,i>>(rec);
            // std::get<idx<p,q>>(ret) += factmint<mint, q> * ifactmint<mint, i> * ifactmint<mint, j> * ifactmint<mint, q-i-j> * aquo.pow(j) * bquo.pow(q-i-j) * std::get<idx<p+j,i>>(rec);
        }
    };
    template<int p, int q, int i, int j>
    struct inner_assign_rec {
        void operator()(std::array<mint, array_size> &rec,
                        std::array<mint, array_size> &ret,
                        mint, mint){
            std::get<idx<p,q>>(ret) -= binommint<mint, q, i> * coef<p, j> * std::get<idx<i,j>>(rec);
        }
    };
    template<int p, int q>
    struct inner_assign_rec<p, q, -1, -1> {
        void operator()(std::array<mint, array_size> &rec,
                        std::array<mint, array_size> &ret,
                        mint n, mint k){
            std::get<idx<p,q>>(ret) += k.pow(q) * power_sum<mint, p>(n);
        }
    };

    static std::array<mint, array_size> inner_floor_sum_pq(Int n, Int m, Int a, Int b){
        if (n <= 0) return {};
        Int aquo = floor_div(a, m);
        Int arem = a - aquo * m;
        Int bquo = floor_div(b, m);
        Int brem = b - bquo * m;
        if (aquo != 0 || bquo != 0){
            auto rec = inner_floor_sum_pq(n, m, arem, brem);
            std::array<mint, array_size> ret = {};
            floor_sum_loop_mod::process_loop4<inner_assign_mod, sumpq>(rec, ret, aquo, bquo);
            return ret;
        }
        Int k = floor_div(a * (n - 1) + b, m);
        auto rec = inner_floor_sum_pq(k, a, m, m - b + a - 1);
        std::array<mint, array_size> ret = {};
        floor_sum_loop_rec::process_loop4<inner_assign_rec, sumpq>(rec, ret, n, k);
        return ret;
    }
};


template<typename T>
struct floor_sum_2_info {
    // pq : 01, 02, 11
    std::array<T, 3> inner_floor_sum_2(T n, T m, T a, T b){
        if (n <= 0) return {};
        if (a == 0) return {};
        T aquo = floor_div(a, m);
        T arem = a - aquo * m;
        T bquo = floor_div(b, m);
        T brem = b - bquo * m;
        if (aquo != 0 || bquo != 0){
            auto rec = inner_floor_sum_2(n, m, arem, brem);
            std::array<T, 3> ret = {};
            // pq : 01
            {
                // ij : 00
                ret[0] += bquo * n;
                // ij : 01
                ret[0] += aquo * (n * (n-1) / 2);
                // ij : 10
                ret[0] += rec[0];
            }
            // pq : 02
            {
                // ij : 00
                ret[1] += bquo * bquo * n;
                // ij : 01
                ret[1] += aquo * bquo * n * (n-1);
                // ij : 10
                ret[1] += 2 * bquo * rec[0];
                // ij : 02
                ret[1] += aquo * aquo * ((n-1) * n / 2 * (2*n-1) / 3);
                // ij : 11
                ret[1] += 2 * aquo * rec[2];
                // ij : 20
                ret[1] += rec[1];
            }
            // pq : 11
            {
                // ij : 00
                ret[2] += bquo * (n * (n-1) / 2);
                // ij : 01
                ret[2] += aquo * ((n-1) * n / 2 * (2*n-1) / 3);
                // ij : 10
                ret[2] += rec[2];
            }
            return ret;
        }
        T k = (a * (n-1) + b) / m;
        auto rec = inner_floor_sum_2(k, a, m, m - b + a - 1);
        std::array<T, 3> ret = {};
        // pq : 01
        {
            ret[0] += n * k - rec[0];
        }
        // pq : 02
        {
            ret[1] += n * k * k - rec[0] - 2 * rec[2];
        }
        // pq : 11
        {
            // ret[2] += (n-1) * n / 2 * k + (rec[0] - rec[1]) / 2;
            ret[2] += ((n-1) * n * k + rec[0] - rec[1]) / 2;
        }
        return ret;
    }
};

} // namespace noya2::internal::floor_sum



// p >= 0, q >= 0
// sum[i in [0, n)] i^p floor(a * i + b / m)^q
template<Modint mint, int p, int q>
mint floor_sum_pq(long long n, long long m, long long a, long long b){
    static noya2::internal::floor_sum::floor_sum_pq_info<mint,p+q> info;
    return info.inner_floor_sum_pq(n, m, a, b)[noya2::internal::floor_sum::floor_sum_pq_info<mint,p+q>::template idx<p,q>];
}

// T = int, long long
// p >= 0, q >= 0, p + q 
// sum[i in [0, n)] i^p floor(a * i + b / m)^q
template<typename T>
std::array<T, 3> floor_sum_2(T n, T m, T a, T b){
    static noya2::internal::floor_sum::floor_sum_2_info<T> info;
    return info.inner_floor_sum_2(n, m, a, b);
}

template<int i, int j>
struct say {
    void operator()(auto ...args){
        std::cout << i << ' ' << j << ' ' << powint<i+j>(args...) << std::endl;
    }
};

template<int p, int q, int i, int j>
struct say4 {
    void operator()(auto ...args){
        std::cout << p << ' ' << q << ' ';
        std::cout << i << ' ' << j << std::endl;
    }
};

ull solve1(ull n, ull m, ull a, ull b1, ull b2){
    if (a == 0){
        return n*b1*b2;
    }
    if (b1 > b2) swap(b1,b2);
    ull ans = 0;
    ans += (n-1)*n/2*(2*n-1)/3 * a*a;
    ans += (n-1)*n/2 * a*(b1+b2);
    ans += b1*b2*n;
    auto sb2 = floor_sum_2(n,m,a,b2);
    ans -= sb2[0] * m * b1;
    ans -= sb2[2] * m * a;
    auto sb1 = floor_sum_2(n,m,a,b1);
    ans -= sb1[0] * m * b2;
    ans -= sb1[2] * m * a;
    ull tot = 0;
    [&]{
        // return ;
        ull k = floor_div(a*(n-1)+b1,m);
        tot += sb1[1];
        auto nsb1 = floor_sum_2(k,a,m,m-b1+a-1);
        tot += nsb1[2];
        auto nsb2 = floor_sum_2(k,a,m,m-b2+a-1);
        tot -= nsb2[2];
        tot += k * (n - min(n, ceil_div((k+1)*m-b2,a)));
    }();
    ans += tot * m * m;
    return ans;
}

ll nn, mm, aa, bb;

template<int p, int q>
void f(){
    using mint = modint998244353;
    out(floor_sum_pq<mint,p,q>(nn+1,mm,aa,bb));
}

template<int p, typename qs>
struct callerpq;

template<int p, int ...qs>
struct callerpq<p, std::integer_sequence<int, qs...>> {
    static void call(int q) {
        ((q == qs ? (f<p, qs>(), 0) : 0), ...);
    }
};

template<typename ps, typename qs>
struct dispatcher;

template<int ...ps, int ...qs>
struct dispatcher<std::integer_sequence<int, ps...>, std::integer_sequence<int, qs...>> {
    static void dispatch(int p, int q) {
        ((p == ps ? (callerpq<ps, std::integer_sequence<int, qs...>>::call(q), 0) : 0), ...);
    }
};

void jikken3(){
    int n; in(n);
    using mint = modint998244353;
    rep(i,n){
        mint a = internal::floor_sum::power_sum<mint, 2>(i);
        mint b = internal::floor_sum::floor_sum_pq_info<mint,2>::template coef<2,0> * mint(i).pow(0)
            + internal::floor_sum::floor_sum_pq_info<mint,2>::template coef<2,1> * mint(i).pow(1)
            + internal::floor_sum::floor_sum_pq_info<mint,2>::template coef<2,2> * mint(i).pow(2)
            + internal::floor_sum::floor_sum_pq_info<mint,2>::template coef<2,3> * mint(i).pow(3);
        out(a,b);
    }
}

void solve2(){
    int p, q; in(p,q);
    ll n, m, a, b; in(n,m,a,b);
    nn = n;
    mm = m;
    aa = a;
    bb = b;
    using range = std::make_integer_sequence<int, 3>;
    dispatcher<range, range>::dispatch(p, q);
}

void solve3(){
    int p, q; in(p,q);
    ll n, m, a, b; in(n,m,a,b);
    using mint = modint998244353;
    if (p + q <= 4){
        auto ans = internal::floor_sum::floor_sum_pq_info<mint, 4>::inner_floor_sum_pq(n+1, m, a, b);
        out(ans[internal::floor_sum::floor_sum_pq_info<mint, 4>::idx_func(p,q)]);
    }
    else {
    	exit(1);
        // auto ans = internal::floor_sum::floor_sum_pq_info<mint, 20>::inner_floor_sum_pq(n+1, m, a, b);
        // out(ans[internal::floor_sum::floor_sum_pq_info<mint, 20>::idx_func(p,q)]);
    }
}

void solve(){
    // jikken3(); return ;
    // solve2(); return ;
    solve3(); return ;
    // ll n, m, a, b1, b2; in(n,m,a,b1,b2);
    // out(ll(solve1(n,m,a,b1,b2)));
    using mint = modint998244353;
    out(internal::floor_sum::factmint<mint,2>);
    out(internal::floor_sum::ifactmint<mint,2>);
    out(internal::floor_sum::bernoulli<mint,2>);
    int n; in(n);
    rep(i,n){
        out(i, internal::floor_sum::power_sum<mint, 0>(i), internal::floor_sum::power_sum<mint, 1>(i), internal::floor_sum::power_sum<mint, 2>(i), internal::floor_sum::power_sum<mint, 3>(i));
    }
}

int main(){
    int t = 1; in(t);
    while (t--) { solve(); }
}
0