結果
| 問題 |
No.214 素数サイコロと合成数サイコロ (3-Medium)
|
| コンテスト | |
| ユーザー |
lumc_
|
| 提出日時 | 2018-09-12 13:22:51 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 6,991 bytes |
| コンパイル時間 | 1,602 ms |
| コンパイル使用メモリ | 175,844 KB |
| 実行使用メモリ | 7,016 KB |
| 最終ジャッジ日時 | 2024-06-26 20:28:20 |
| 合計ジャッジ時間 | 2,776 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | RE * 3 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
// #undef DEBUG
// #define DEBUG
// DEBUG {{{
// clang-format off
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\n";}()
template < class T > inline void dump2D(T &d, size_t sizey, size_t sizex) { for(size_t i = 0; i < sizey; i++) { DEBUG_OUT << "\t"; for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << (j + 1 == sizex ? "" : "\t"); DEBUG_OUT << endl; } }
template < class T, class = typename iterator_traits< typename T::iterator >::value_type, class = typename enable_if<!is_same<T, string>::value>::type > ostream &operator<<(ostream &o, const T &a) { o << "{"; for(auto ite = a.begin(); ite != a.end(); ++ite) o << (ite == a.begin() ? "" : ", ") << *ite; o << "}"; return o; }
#else
#define dump(...) (42)
#define dump2D(...) (42)
template < class T, class = typename iterator_traits< typename T::iterator >::value_type, class = typename enable_if<!is_same<T, string>::value>::type > ostream &operator<<(ostream &o, const T &a) { for(auto ite = a.begin(); ite != a.end(); ++ite) o << (ite == a.begin() ? "" : " ") << *ite; return o; }
#endif
// clang-format on
// }}}
/// --- ModInt Library {{{ ///
template < ll mod = (ll) 1e9 + 7 >
struct ModInt {
static ll extgcd(ll a, ll b, ll &x, ll &y) {
ll d;
return b == 0 ? (x = 1, y = 0, a)
: (d = extgcd(b, a % b, y, x), y -= a / b * x, d);
}
static ll modinv(ll a) {
ll x = 0, y = 0;
extgcd(a, mod, x, y);
return (x + mod) % mod;
}
ll val;
constexpr ModInt() : val(0) {}
constexpr ModInt(ll val) : val((val % mod + mod) % mod) {}
ModInt operator+(ModInt const &rhs) const { return ModInt(val + rhs.val); }
ModInt operator-(ModInt const &rhs) const { return ModInt(val - rhs.val); }
ModInt operator*(ModInt const &rhs) const { return ModInt(val * rhs.val); }
ModInt operator/(ModInt const &rhs) const {
return ModInt(val * rhs.inv().val);
}
ModInt &operator+=(ModInt const &rhs) {
val = ((val + rhs.val) % mod + mod) % mod;
return *this;
}
ModInt &operator-=(ModInt const &rhs) {
val = ((val - rhs.val) % mod + mod) % mod;
return *this;
}
ModInt &operator*=(ModInt const &rhs) {
val = (val * rhs.val % mod + mod) % mod;
return *this;
}
ModInt &operator/=(ModInt const &rhs) {
val = (val * rhs.inv().val % mod + mod) % mod;
return *this;
}
ModInt operator++(int) {
ModInt tmp = *this;
val = val + 1;
if(val >= mod) val = 0;
return tmp;
}
ModInt operator--(int) {
ModInt tmp = *this;
val = val == 0 ? mod - 1 : val - 1;
return tmp;
}
ModInt &operator++() {
val = val + 1;
if(val >= mod) val = 0;
return *this;
}
ModInt &operator--() {
val = val == 0 ? mod - 1 : val - 1;
return *this;
}
ModInt operator-() const { return ModInt(-val); }
template < typename T >
ModInt operator+(T const &rhs) const {
return ModInt(val + rhs % mod);
}
template < typename T >
ModInt operator-(T const &rhs) const {
return ModInt(val - rhs % mod);
}
template < typename T >
ModInt operator*(T const &rhs) const {
return ModInt(val * (rhs % mod));
}
template < typename T >
ModInt operator/(T const &rhs) const {
return ModInt(val * modinv(rhs));
}
template < typename T >
ModInt &operator+=(T const &rhs) {
val = ((val + rhs % mod) % mod + mod) % mod;
return *this;
}
template < typename T >
ModInt &operator-=(T const &rhs) {
val = ((val - rhs % mod) % mod + mod) % mod;
return *this;
}
template < typename T >
ModInt &operator*=(T const &rhs) {
val = (val * (rhs % mod) % mod + mod) % mod;
return *this;
}
template < typename T >
ModInt &operator/=(T const &rhs) {
val = (val * modinv(rhs, mod) % mod + mod) % mod;
return *this;
}
ModInt inv() const { return ModInt(modinv(val)); }
friend ostream &operator<<(ostream &os, ModInt const &mv) {
os << mv.val;
return os;
}
friend constexpr ModInt operator+(ll a, ModInt const &mv) {
return ModInt(a % mod + mv.val);
}
friend constexpr ModInt operator-(ll a, ModInt const &mv) {
return ModInt(a % mod - mv.val);
}
friend constexpr ModInt operator*(ll a, ModInt const &mv) {
return ModInt(a % mod * mv.val);
}
friend constexpr ModInt operator/(ll a, ModInt const &mv) {
return ModInt(a % mod * mv.inv().val);
}
};
/// }}}--- ///
using Int = ModInt<>;
template < class T >
vector< T > kitamasa(const vector< T > &c, const vector< T > &u,
const vector< T > &v) {
int k = c.size();
vector< T > r(2 * k - 1);
for(int i = 0; i < k; i++)
for(int j = 0; j < k; j++) r[i + j] += u[i] * v[j];
for(int i = 2 * k - 2; i >= k; i--)
for(int j = 0; j < k; j++) r[i - k + j] += r[i] * c[j];
r.resize(k);
return r;
}
int P[] = {2,3,5,7,11,13};
int C[] = {4,6,8,9,10,12};
const int PS = 6;
const int N = 1e5;
const int K = 1250 + 10; // 13P + 12C
const int PN = 30;
Int dpP[PS + 1][PN + 1][K];
Int dpC[PS + 1][PN + 1][K];
vector<Int> dp2(K);
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0);
ll n, p, c;
cin >> n >> p >> c;
dpP[0][0][0] = 1;
dpC[0][0][0] = 1;
for(int i = 1; i <= PS; i++) {
for(int j = 0; j <= p; j++) {
for(int k = 0; k <= p; k++) {
for(int l = 0; l < K; l++) {
if(k-j>=0 && l - P[i-1]*j >= 0) dpP[i][k][l] += dpP[i-1][k-j][l - P[i-1] * j];
}
}
}
}
for(int i = 1; i <= PS; i++) {
for(int j = 0; j <= c; j++) {
for(int k = 0; k <= c; k++) {
for(int l = 0; l < K; l++) {
if(k-j>=0 && l - C[i-1]*j >= 0) dpC[i][k][l] += dpC[i-1][k-j][l - C[i-1] * j];
}
}
}
}
for(int i = 0; i < K; i++){
for(int j = 0; j < K; j++) {
if(i + j < K) dp2[i + j] += dpP[PS][p][i] * dpC[PS][c][j];
}
}
reverse(begin(dp2), end(dp2));
dp2.pop_back();
// aa(i) = a(i+K-2) とする
// aa(n) = a(n+K-2)
vector<Int> r(K-1, 0); r[0] = 1;
vector<Int> t(K-1, 0); t[1] = 1;
ll tn = n+K-2;
while(tn) {
if(tn&1) r = kitamasa(dp2, r, t);
t = kitamasa(dp2, t, t);
tn >>= 1;
}
Int ans = 0;
for(int i = 0; i < K-1; i++) ans += r[i]; // a[i] = 1 としてやるといい
cout << ans << endl;
return 0;
}
lumc_