結果
問題 | No.213 素数サイコロと合成数サイコロ (3-Easy) |
ユーザー | rpy3cpp |
提出日時 | 2015-08-24 19:04:27 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 171 ms / 3,000 ms |
コード長 | 2,361 bytes |
コンパイル時間 | 256 ms |
コンパイル使用メモリ | 82,164 KB |
実行使用メモリ | 76,472 KB |
最終ジャッジ日時 | 2024-07-18 13:10:36 |
合計ジャッジ時間 | 997 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 115 ms
76,360 KB |
testcase_01 | AC | 171 ms
76,472 KB |
ソースコード
def solve(N, P, C): mod = 10 ** 9 + 7 ps = [2-2, 3-2, 5-2, 7-2, 11-2, 13-2] cs = [4-4, 6-4, 8-4, 9-4, 10-4, 12-4] distp = get_dist(ps, P) distc = get_dist(cs, C) dist = merge_dists(distp, distc) coefs = [0] * (2 * P + 4 * C - 1) + dist coefs.reverse() inits = set_inits(coefs, mod) inits_tricked = trick_inits(inits, coefs, mod) return LRS(inits_tricked, coefs, N - 1, mod) def set_inits(coefs, mod): inits = [1] n = len(coefs) for i in range(1, n): v = sum(a * c for a, c, in zip(inits, coefs[-i:])) % mod inits.append(v) return inits def trick_inits(bs, coefs, mod): k = len(coefs) inits = [0] * k for i in range(k): bbs = [0] * i + bs[:k - i] tmp = sum(coefs[:k - i]) for j in range(k): inits[j] += bbs[j] * tmp return inits def get_dist(qs, Q): len_dp = qs[-1] * Q + 1 dp = [[0] * len_dp for n in range(Q + 1)] dp[0][0] = 1 for q in qs: for n in range(1, Q + 1): current_dp = dp[n] prev_dp = dp[n - 1] for s in range(q, q * n + 1): current_dp[s] += prev_dp[s - q] return dp[Q] def merge_dists(distp, distc): mod = 10 ** 9 + 7 len_p = len(distp) len_c = len(distc) dist = [0] * (len_p + len_c - 1) for i, pi in enumerate(distp): for ij, cj in enumerate(distc, i): dist[ij] += pi * cj dist[ij] %= mod return dist def poly_mult(poly1, poly2, f, mod): n = len(f) poly_long = [0] * (2 * n - 1) for i, p1 in enumerate(poly1): for j, p2 in enumerate(poly2): poly_long[i + j] += p1 * p2 for i in range(2 * n - 2, n - 1, -1): p = poly_long[i] % mod for j, fk in enumerate(f, i - n): poly_long[j] += p * fk poly = [p % mod for p in poly_long[:n]] return poly def poly_pow(f, p, mod): n = len(f) polyR = [0] * n polyR[0] = 1 poly = [0] * n poly[1] = 1 while p: if p & 1: polyR = poly_mult(poly, polyR, f, mod) poly = poly_mult(poly, poly, f, mod) p >>= 1 return polyR def LRS(As, Cs, n, mod): poly = poly_pow(Cs, n, mod) return sum(p * a for p, a in zip(poly, As)) % mod if __name__ == '__main__': N, P, C = map(int, input().split()) print(solve(N, P, C))