結果
問題 | No.213 素数サイコロと合成数サイコロ (3-Easy) |
ユーザー | mayoko_ |
提出日時 | 2015-05-23 14:13:25 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 12 ms / 3,000 ms |
コード長 | 3,540 bytes |
コンパイル時間 | 1,982 ms |
コンパイル使用メモリ | 180,836 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-07-06 06:18:46 |
合計ジャッジ時間 | 2,338 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 7 ms
5,248 KB |
testcase_01 | AC | 12 ms
5,376 KB |
ソースコード
#include <bits/stdc++.h> #define rep(i, n) for (int (i) = 0; (i) < (int)(n); (i)++) const int dx[] = {1, 0, -1, 0}; const int dy[] = {0, 1, 0, -1}; using namespace std; typedef long long ll; typedef vector<int> vi; typedef vector<ll> vll; typedef pair<int, int> pii; const int a[] = {2,3,5,7,11,13}; const int b[] = {4,6,8,9,10,12}; typedef vector<ll> vec; typedef vector<vec> matrix; const ll MOD = 1e9+7; matrix mul(const matrix& A, const matrix& B) { int n = A.size(); int m = B[0].size(); int k = A[0].size(); matrix ret(n, vec(m)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { for (int l = 0; l < k; l++) { (ret[i][j] += A[i][l] * B[l][j]) %= MOD; } } } return ret; } // kitamasa専用でおねがいします matrix kitamasaMul(const matrix& A, const matrix& B) { int n = A.size(); assert(n == 1); int m = B[0].size(); matrix ret(n, vec(m)); ret[0][0] = A[0][m-1]*B[m-1][0] % MOD; for (int i = 1; i < m; i++) { ret[0][i] = (A[0][i-1] + A[0][m-1]*B[m-1][i]) % MOD; } return ret; } // Aのm乗を求める // Aの形は一番下だけ任意の整数で良くて残りの行はA[i][i+1]のみ1 matrix kitamasa(const matrix& A, ll m) { int n = A.size(); matrix B = A; matrix u(1, vec(n)); u[0][0] = 1; matrix a(1, vec(n)); while (m) { if (m&1) { u = mul(u, B); } for (int i = 0; i < n; i++) a[0][i] = B[0][i]; a = mul(a, B); for (int i = 0; i < n; i++) B[0][i] = a[0][i]; for (int i = 1; i < n; i++) { a = kitamasaMul(a, A); for (int j = 0; j < n; j++) { B[i][j] = a[0][j]; } } m /= 2; } matrix ret(n, vec(n)); for (int i = 0; i < n; i++) ret[0][i] = u[0][i]; for (int i = 1; i < n; i++) { u = kitamasaMul(u, A); for (int j = 0; j < n; j++) { ret[i][j] = u[0][j]; } } return ret; } const int MAXP = 10, MAXC = 10; int P, C; ll N; set<vi> S1, S2; void dfsp(int p, vi v) { if (p == P) { sort(v.begin(), v.end()); S1.insert(v); return; } for (int i = 0; i < 6; i++) { v.push_back(a[i]); dfsp(p+1, v); v.pop_back(); } } void dfsc(int c, vi v) { if (c == C) { sort(v.begin(), v.end()); S2.insert(v); return; } for (int i = 0; i < 6; i++) { v.push_back(b[i]); dfsc(c+1, v); v.pop_back(); } } ll memo[MAXP*20][3]; int main() { cin.tie(0); ios::sync_with_stdio(false); cin >> N >> P >> C; // 素数 dfsp(0, vi()); // 合成数 dfsc(0, vi()); for (vi el : S1) { int tmp = 0; for (int a : el) tmp += a; memo[tmp][0]++; } for (vi el : S2) { int tmp = 0; for (int a : el) tmp += a; memo[tmp][1]++; } if (P == 0) memo[0][0] = 1; if (C == 0) memo[0][1] = 1; for (int i = 0; i < MAXP*10; i++) for (int j = 0; j < MAXP*10; j++) { (memo[i+j][2] += memo[i][0] * memo[j][1]) %= MOD; } int tmp = P*13+C*12; matrix A(tmp, vec(tmp)); for (int i = 0; i < tmp-1; i++) { A[i][i+1] = 1; } for (int i = 1; i <= tmp; i++) { A[tmp-1][tmp-i] = memo[i][2]; } A = kitamasa(A, N); ll ans = 0; for (int i = 0; i < tmp; i++) { (ans += A[tmp-1][i]) %= MOD; } cout << ans << endl; return 0; }