結果

問題 No.214 素数サイコロと合成数サイコロ (3-Medium)
ユーザー antaanta
提出日時 2015-11-14 18:08:22
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 360 ms / 3,000 ms
コード長 1,741 bytes
コンパイル時間 817 ms
コンパイル使用メモリ 67,156 KB
実行使用メモリ 4,380 KB
最終ジャッジ日時 2023-08-25 02:18:56
合計ジャッジ時間 2,575 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 355 ms
4,380 KB
testcase_01 AC 328 ms
4,376 KB
testcase_02 AC 360 ms
4,380 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
using namespace std;
typedef long long ll;

typedef vector<int> Poly;
const int Mod = 1000000007;

inline void add(int &x, int y) { if((x += y) >= Mod) x -= Mod; }

Poly doDP(const int a[6], int n) {
	vector<Poly> dp(n+1, Poly(a[5] * n + 1));
	dp[0][0] = 1;
	int z = a[0];
	rep(k, 6) {
		int d = a[k];
		for(int t = 0; t < n; ++ t)
			for(int i = t * z; i <= t * d; ++ i)
				add(dp[t + 1][i + d], dp[t][i]);
	}
	return dp[n];
}

Poly mul(const Poly &p, const Poly &q) {
	int pn = p.size(), qn = q.size();
	if(pn == 0 || qn == 0) return Poly();
	Poly r(pn + qn - 1);
	rep(i, pn) rep(j, qn)
		add(r[i + j], (ll)p[i] * q[j] % Mod);
	return r;
}

Poly rem(const Poly &p, const Poly &q) {
	int pd = p.size() - 1, qd = q.size() - 1;
	if(pd < qd) return p;
	Poly r = p;
	for(int i = pd; i >= qd; -- i) {
		int t = Mod - r[i];
		rep(j, qd)
			add(r[i - qd + j], (ll)t * q[j] % Mod);
	}
	r.resize(qd);
	return r;
}

Poly powmod(const Poly &t, ll K, const Poly &q) {
	Poly p = rem(t, q);
	int l = 0;
	while((K >> l) > 1) ++ l;
	Poly res = p;
	for(-- l; l >= 0; -- l) {
		res = rem(mul(res, res), q);
		if(K >> l & 1)
			res = rem(mul(res, p), q);
	}
	return res;
}

int main() {
	long long N; int P, C;
	cin >> N >> P >> C;
	const int ps[6] = { 2, 3, 5, 7, 11, 13 };
	const int cs[6] = { 4, 6, 8, 9, 10, 12 };
	vector<int> cntP, cntC;
	cntP = doDP(ps, P);
	cntC = doDP(cs, C);
	int X = P * ps[5] + C * cs[5];
	Poly pc = mul(cntP, cntC);
	pc.resize(X + 1);
	Poly mod(X + 1);
	rep(i, X)
		mod[i] = Mod - pc[X - i];
	mod[X] = 1;
	Poly v = powmod(Poly{{0, 1}}, X + (N - 1), mod);
	ll ans = 0;
	rep(i, v.size()) ans += v[i];
	printf("%d\n", ans % Mod);
	return 0;
}
0