結果

問題 No.58 イカサマなサイコロ
ユーザー not_522
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

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

#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;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1