結果

問題 No.1547 [Cherry 2nd Tune *] 偶然の勝利の確率
ユーザー midri1784midri1784
提出日時 2021-06-11 23:53:25
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 248 ms / 2,000 ms
コード長 7,915 bytes
コンパイル時間 2,974 ms
コンパイル使用メモリ 215,208 KB
実行使用メモリ 5,376 KB
最終ジャッジ日時 2024-05-08 20:32:53
合計ジャッジ時間 6,136 ms
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 9 ms
5,376 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 AC 2 ms
5,376 KB
testcase_05 AC 2 ms
5,376 KB
testcase_06 AC 1 ms
5,376 KB
testcase_07 AC 2 ms
5,376 KB
testcase_08 AC 2 ms
5,376 KB
testcase_09 AC 2 ms
5,376 KB
testcase_10 AC 2 ms
5,376 KB
testcase_11 AC 2 ms
5,376 KB
testcase_12 AC 2 ms
5,376 KB
testcase_13 AC 42 ms
5,376 KB
testcase_14 AC 27 ms
5,376 KB
testcase_15 AC 12 ms
5,376 KB
testcase_16 AC 19 ms
5,376 KB
testcase_17 AC 20 ms
5,376 KB
testcase_18 AC 19 ms
5,376 KB
testcase_19 AC 7 ms
5,376 KB
testcase_20 AC 134 ms
5,376 KB
testcase_21 AC 13 ms
5,376 KB
testcase_22 AC 2 ms
5,376 KB
testcase_23 AC 237 ms
5,376 KB
testcase_24 AC 242 ms
5,376 KB
testcase_25 AC 239 ms
5,376 KB
testcase_26 AC 248 ms
5,376 KB
testcase_27 AC 238 ms
5,376 KB
testcase_28 AC 239 ms
5,376 KB
testcase_29 AC 234 ms
5,376 KB
testcase_30 AC 239 ms
5,376 KB
testcase_31 AC 232 ms
5,376 KB
testcase_32 AC 237 ms
5,376 KB
testcase_33 AC 233 ms
5,376 KB
testcase_34 AC 19 ms
5,376 KB
testcase_35 AC 18 ms
5,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>

using namespace std;

typedef long long i64;
typedef unsigned long long ui64;
typedef vector<i64> vi;
typedef vector<vi> vvi;
typedef pair<i64, i64> pi;

#define pb push_back
#define sz(a) i64((a).size())
#define all(c) (c).begin(), (c).end()
#define REP(s, e, i) for(i=(s); i < (e); ++i)
inline void RI(i64 &i) {scanf("%lld", &(i));}
inline void RVI(vi &v) { for(i64 i=0;i<sz(v);++i) { RI(v[i]); } }
inline void RVVI(vvi &vv) { for(i64 i=0;i<sz(vv);++i) { RVI(vv[i]); } }
inline void WI(const i64 &i) {printf("%lld\n", i);}
inline void WVI(const vi &v, char sep=' ') { for(i64 i=0;i<sz(v);++i) { if(i != 0){ printf("%c", sep); } printf("%lld", v[i]);} printf("\n"); }
inline void WS(const string &s) { printf("%s\n", s.c_str()); }
inline void WB(bool b, const string &yes, const string &no) { if(b){ WS(yes);} else { WS(no);} }
inline void YESNO(bool b) { WB(b, "YES", "NO"); }
inline void YesNo(bool b) { WB(b, "Yes", "No"); }
#define BUF_LENGTH 1000000
inline void RS(string &s) {static char buf[BUF_LENGTH]; scanf("%s", buf); s = buf;}
template<typename T> inline bool IN(T &S, const typename T::key_type &key) {
  return S.find(key) != S.end();
}
template<typename T> inline bool ON(const T &b, i64 idx) {
  return ((T(1) << idx) & b) != 0;
}

template<long long M, typename T=long long>
struct modint {
  modint(T v=T(0)) : val((v >= 0 ? v : (M - ((-v) % M))) % M) {}
  using this_type = modint<M, T>;
  T val;
  this_type operator++(int) {
    this_type ret = *this;
    val++; val %= M;
    return ret;
  }
  this_type operator--(int) {
    this_type ret = *this;
    val += M-1; val %= M;
    return ret;
  }
  this_type &operator++() {
    val++; val %= M;
    return *this;
  }
  this_type &operator--() {
    val += M-1; val %= M;
    return *this;
  }
  this_type operator+() const { return *this; }
  this_type operator-() const { return this_type(M-val); };
  friend this_type operator+(const this_type &lhs, const this_type &rhs) {
    return this_type(lhs) += rhs;
  }
  friend this_type operator-(const this_type &lhs, const this_type &rhs) {
    return this_type(lhs) -= rhs;
  }
  friend this_type operator*(const this_type &lhs, const this_type &rhs) {
    return this_type(lhs) *= rhs;
  }
  friend this_type operator/(const this_type &lhs, const this_type &rhs) {
    return this_type(lhs) /= rhs;
  }
  this_type pow(long long b) const {
    this_type ret = 1, a = *this;    
    while(b != 0) {
      if(b % 2 != 0) {
        ret *= a;
      }
      b /= 2;
      a = a * a;
    }
    return ret;
  }
  this_type inv() const {
    return pow(M-2);
  }
  this_type& operator+=(const this_type &rhs) {
    val += rhs.val; val %= M; return *this;
  }
  this_type& operator-=(const this_type &rhs) {
    val += M - rhs.val; val %= M; return *this;
  }
  this_type& operator*=(const this_type &rhs) {
    val *= rhs.val; val %= M; return *this;
  }
  this_type& operator/=(const this_type &rhs) {
    *this *= rhs.inv(); return *this;
  }
  friend bool operator==(const this_type &lhs, const this_type &rhs) {
    return lhs.val == rhs.val;
  }
  friend bool operator!=(const this_type &lhs, const this_type &rhs) {
    return lhs.val != rhs.val;
  }
  T mod() const {return M;}
};

using mi = modint<998244353>;
//using mi = modint<1000000007>;
using vmi = vector<mi>;
using vvmi = vector<vmi>;

// row initializers
  
template<typename T>
vector<T> init_row(size_t cols) {
  return vector<T>(cols, 0);
}

template<typename T, typename R = vector<T>>
class matrix_ {
public:
  using this_type = matrix_<T>;
  matrix_(size_t rows, size_t cols) {
    assert(rows > 0 && cols > 0);
    data.resize(rows, init_row<T>(cols));
  }
  
  matrix_(const vector<R> &values) {
    assert(!values.empty());
    data = values;
  }

  T& operator()(size_t r, size_t c) {
    assert(0 <= r && r < rows());
    assert(0 <= c && c < cols());
    return data[r][c];
  }

  const T& operator()(size_t r, size_t c) const {
    assert(0 <= r && r < rows());
    assert(0 <= c && c < cols());
    return data[r][c];
  }

  /////
  // matrix-matrix operations
  this_type &operator+=(const this_type &rhs) {
    assert(rows() == rhs.rows() && cols() == rhs.cols());
    for(size_t r=0;r<rows;++r) { for(size_t c=0;c<cols;++c) {
      (*this)(r, c) += rhs(r, c);
    }}
    return *this;
  }

  this_type &operator-=(const this_type &rhs) {
    assert(rows() == rhs.rows() && cols() == rhs.cols());
    for(size_t r=0;r<rows;++r) { for(size_t c=0;c<cols;++c) {
      (*this)(r, c) -= rhs(r, c);
    }}
    return *this;
  }

  this_type operator*=(const this_type &rhs) {
    assert(cols() == rhs.rows());
    this_type res(rows(), rhs.cols());
    for(size_t r=0;r<rows();++r) { for(size_t c=0;c<rhs.cols(); ++c) {
      for(size_t i=0;i<cols();++i) {
        res(r, c) += (*this)(r, i) * rhs(i, c);
      }
    }}
    (*this).swap(res);
    return *this;
  }

  friend this_type operator+(const this_type &lhs, const this_type &rhs) {
    return this_type(lhs) += rhs;
  }
  friend this_type operator-(const this_type &lhs, const this_type &rhs) {
    return this_type(lhs) -= rhs;
  }
  friend this_type operator*(const this_type &lhs, const this_type &rhs) {
    return this_type(lhs) *= rhs;
  }

  /////
  // matrix-scalar operations
  this_type operator+=(const T &rhs) {
    for(size_t r=0;r<rows();++r) { for(size_t c=0;c<cols(); ++c) {
      (*this)(r, c) += rhs;
    } }
    return *this;
  }
  this_type operator-=(const T &rhs) {
    (*this) += (-rhs);
    return *this;
  }
  this_type operator*=(const T &rhs) {
    for(size_t r=0;r<rows();++r) { for(size_t c=0;c<cols(); ++c) {
      (*this)(r, c) *= rhs;
    } }
    return *this;
  }

  this_type operator+() const {return *this; }
  this_type operator-() const {this_type res(data); res *= -1; return res; };

  size_t rows() const { return data.size(); }
  size_t cols() const { return data[0].size(); }
  
  void swap(this_type &rhs) {
    data.swap(rhs.data);
  }

private:
  vector<R> data;
};

using matrix = matrix_<mi>;

matrix matpow(const matrix &a, i64 p) {
  matrix res(a.rows(), a.cols());
  for(i64 i=0;i<res.rows();++i) { // set identity
    res(i, i) = 1;
  }
  matrix aa = a;
  while(p != 0) {
    if(p % 2 == 1) {
      res = res * aa;
    }
    aa = aa * aa;
    p /= 2;
  }  
  return res;
}

int main(int argc, char *argv[]) {
  i64 i, j, k;

  i64 MA, NA, S; cin >> MA >> NA >> S;  
  i64 MB, NB, T; cin >> MB >> NB >> T;
  i64 K; cin >> K;

  i64 SIZE = S + T + 1;
  matrix XA(SIZE, SIZE), XB(SIZE, SIZE);
  // X = idx - T
  auto v2i = [&](i64 v) {
    return v + T;
  };

  // make XA
  XA(0, 0) = XA(S+T, S+T) = 1;
  mi PA = mi(MA) * mi(NA).inv();
  mi RA = 1 - PA;
  for(i64 v=-T+1;v<S;++v) {
    XA(v2i(v), v2i(v)) = RA;
    mi PS = RA;
    for(i64 u=v+1;u<S;++u) {
      XA(v2i(u), v2i(v)) = XA(v2i(u-1), v2i(v)) * PA;
      PS += XA(v2i(u), v2i(v));
    }
    XA(v2i(S), v2i(v)) = 1 - PS;
  }

  // make XB
  XB(0, 0) = XB(S+T, S+T) = 1;
  mi PB = mi(MB) * mi(NB).inv();
  mi RB = 1 - PB;
  for(i64 v=-T+1;v<S;++v) {
    XB(v2i(v), v2i(v)) = RB;
    mi PS = RB;
    for(i64 u=v-1;u>-T;--u) {
      XB(v2i(u), v2i(v)) = XB(v2i(u+1), v2i(v)) * PB;
      PS += XB(v2i(u), v2i(v));
    }
    XB(v2i(-T), v2i(v)) = 1 - PS;
  }

#if 0
  REP(0, SIZE, i) {
    REP(0, SIZE, j) {
      cerr << XA(i,j).val << " ";
    }
    cerr << endl;
  }
  REP(0, SIZE, i) {
    REP(0, SIZE, j) {
      cerr << XB(i,j).val << " ";
    }
    cerr << endl;
  }
#endif

  matrix X = XB * XA;
#if 0
  REP(0, SIZE, i) {
    REP(0, SIZE, j) {
      cerr << X(i,j).val << " ";
    }
    cerr << endl;
  }
#endif
  matrix XP = matpow(X, K);

  matrix U(SIZE, 1);
  U(v2i(0), 0) = 1;
  matrix V = XP * U;

#if 0
  REP(0, SIZE, i) {
    cerr << U(i,0).val << " ";
  }
  cerr << endl;
  REP(0, SIZE, i) {
    cerr << V(i,0).val << " ";
  }
  cerr << endl;
#endif

  WI(V(v2i(S), 0).val);
  WI(V(v2i(-T), 0).val);

  return 0;
}

0