結果
| 問題 |
No.213 素数サイコロと合成数サイコロ (3-Easy)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 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 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 2 |
ソースコード
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))