結果
問題 | No.58 イカサマなサイコロ |
ユーザー |
![]() |
提出日時 | 2015-07-19 18:34:50 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 4 ms / 5,000 ms |
コード長 | 5,366 bytes |
コンパイル時間 | 1,448 ms |
コンパイル使用メモリ | 174,756 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-07-08 10:22:17 |
合計ジャッジ時間 | 2,133 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 10 |
ソースコード
#include <bits/stdc++.h>using namespace std;namespace arithmetic {template<typename T> class Addition {public:template<typename V> T operator+(const V& v) const {T res(static_cast<const T&>(*this));return res += static_cast<T>(v);}};template<typename T> class Subtraction {public:template<typename V> T operator-(const V& v) const {T res(static_cast<const T&>(*this));return res -= static_cast<T>(v);}};template<typename T> class Multiplication {public:template<typename V> T operator*(const V& v) const {T res(static_cast<const T&>(*this));return res *= static_cast<T>(v);}};template<typename T> class Division {public:template<typename V> T operator/(const V& v) const {T res(static_cast<const T&>(*this));return res /= static_cast<T>(v);}};template<typename T> class Modulus {public:template<typename V> T operator%(const V& v) const {T res(static_cast<const T&>(*this));return res %= static_cast<T>(v);}};}template<typename T> class IndivisibleArithmetic : public arithmetic::Addition<T>, public arithmetic::Subtraction<T>, public arithmetic::Multiplication<T> {};template<typename T> class Arithmetic : public IndivisibleArithmetic<T>, public arithmetic::Division<T> {};template<typename T> class Vector : public arithmetic::Addition<Vector<T>>, public arithmetic::Subtraction<Vector<T>> {protected:vector<T> val;public:Vector(int n) : val(n, 0) {}T& operator[](int n) {return val[n];}Vector operator+=(const Vector& v) {for (int i = 0; i < size(); ++i) val[i] += v[i];return *this;}Vector operator-=(const Vector& v) {for (int i = 0; i < size(); ++i) val[i] -= v[i];return *this;}T operator*(const Vector& v) const {return inner_product(val.begin(), val.end(), const_cast<Vector&>(v).begin(), T(0));}int size() const {return val.size();}typename vector<T>::const_iterator begin() const {return val.begin();}typename vector<T>::const_iterator end() const {return val.end();}};template<typename T> class Matrix : public arithmetic::Addition<Matrix<T>>, public arithmetic::Subtraction<Matrix<T>> {protected:vector<Vector<T>> val;public:Matrix(int n, int m) : val(n, Vector<T>(m)) {}Vector<T>& operator[](int n) {return val[n];}Matrix operator+=(const Matrix& m) {for (int i = 0; i < (int)val.size(); ++i) val[i] += m[i];return *this;}Matrix operator-=(const Matrix& m) {for (int i = 0; i < (int)val.size(); ++i) val[i] -= m[i];return *this;}Matrix operator*=(const Matrix& _m) {Matrix &m = const_cast<Matrix&>(_m);Matrix res(size(), m[0].size());for (int i = 0; i < size(); ++i) {for (int j = 0; j < m.size(); ++j) {for (int k = 0; k < m[0].size(); ++k) {res[i][k] += val[i][j] * m[j][k];}}}return *this = res;}Matrix operator*(const Matrix& m) const {Matrix res = *this;return res *= m;}Vector<T> operator*(const Vector<T>& v) {Vector<T> res(size());for (int i = 0; i < size(); ++i) res[i] += val[i] * v;return res;}int size() const {return val.size();}};template<typename T> class SquareMatrix : public Matrix<T>, public arithmetic::Division<SquareMatrix<T>> {public:SquareMatrix(int n) : Matrix<T>(n, n) {}SquareMatrix(const Matrix<T>& m) : Matrix<T>(m) {}SquareMatrix operator/=(const SquareMatrix& m) {return *this *= m.inverse();}SquareMatrix identity() const {SquareMatrix res(this->size());for (int i = 0; i < this->size(); ++i) res[i][i] = 1;return res;}SquareMatrix inverse() const {int n = this->size();SquareMatrix mat = *this;SquareMatrix inv = identity();for (int i = 0; i < n; ++i) {int p = i;for (int j = i + 1; j < n; ++j) {if (abs(mat[j][i]) > abs(mat[p][i])) p = j;}swap(mat[i], mat[p]);swap(inv[i], inv[p]);for (int j = i + 1; j < n; ++j) mat[i][j] /= mat[i][i];for (int j = 0; j < n; ++j) inv[i][j] /= mat[i][i];mat[i][i] = 1;for (int j = 0; j < n; ++j) {if (i == j) continue;T a = mat[j][i];for (int k = 0; k < n; ++k) {mat[j][k] -= a * mat[i][k];inv[j][k] -= a * inv[i][k];}}}return inv;}};template<typename T> T pow(T& m, long long n) {if (n == 0) {return m.identity();} else if (n < 0) {return m.identity() / pow(m, -n);}T mm = pow(m, n / 2);mm *= mm;if (n % 2) mm *= m;return mm;}int main() {int n, k;cin >> n >> k;const int mx = 6 * n;SquareMatrix<double> m1(mx + 1), m2(mx + 1);for (int i = 0; i < mx; ++i) {for (int j = 1; j <= 6; ++j) {if (i + j <= mx) m1[i + j][i] = 1.0 / 6;}for (int j = 4; j <= 6; ++j) {if (i + j <= mx) m2[i + j][i] = 2.0 / 6;}}Vector<double> v(mx + 1);v[0] = 1;auto taro = (Matrix<double>)pow(m1, n - k) * (Matrix<double>)pow(m2, k) * v;auto jiro = pow(m1, n) * v;double res = 0;for (int i = 0; i <= mx; ++i) {for (int j = 0; j < i; ++j) res += taro[i] * jiro[j];}cout << fixed << setprecision(15) << res << endl;}