結果
| 問題 |
No.2798 Multiple Chain
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-06-28 22:21:49 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 855 ms / 2,000 ms |
| コード長 | 3,314 bytes |
| コンパイル時間 | 166 ms |
| コンパイル使用メモリ | 82,184 KB |
| 実行使用メモリ | 215,624 KB |
| 最終ジャッジ日時 | 2024-06-28 22:22:39 |
| 合計ジャッジ時間 | 46,634 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 51 |
ソースコード
import sys, random
input = lambda : sys.stdin.readline().rstrip()
write = lambda x: sys.stdout.write(x+"\n"); writef = lambda x: print("{:.12f}".format(x))
debug = lambda x: sys.stderr.write(x+"\n")
YES="Yes"; NO="No"; pans = lambda v: print(YES if v else NO); INF=10**18
LI = lambda v=0: list(map(lambda i: int(i)-v, input().split())); II=lambda : int(input()); SI=lambda : [ord(c)-ord("a") for c in input()]
def debug(_l_):
for s in _l_.split():
print(f"{s}={eval(s)}", end=" ")
print()
def dlist(*l, fill=0):
if len(l)==1:
return [fill]*l[0]
ll = l[1:]
return [dlist(*ll, fill=fill) for _ in range(l[0])]
from math import gcd
import random
def is_prime(n):
"""miller_rabinによる素数判定
※ 1は素数と扱う
"""
l = [2,3,5,7,11,13,17,19,23,29,31,37]
if n==1 or n in l:
return True
d = n-1
s = 0
while d%2==0:
s += 1
d //= 2
for a in l:
v = pow(a,d,n)
if v==1 or v==n-1:
continue
for _ in range(s):
v = v*v % n
if v==n-1:
break
else:
return False
return True
def rho(n):
"""nを割り切る3以上の素数を返す(素数のときnを返す)
"""
if is_prime(n):
return n
while True:
x = y = random.randint(1,n-1)
g = 1
while g==1:
x = (x*x - 3) % n
y = (y*y - 3) % n
y = (y*y - 3) % n
g = gcd((x-y), n)
if g>1:
return rho(g)
def factor(n):
"""高速な素因数分解
"""
if n==1:
return {}
f = is_prime(n)
if f:
return {n:1}
ans = {}
while n%2==0:
ans.setdefault(2, 0)
ans[2] += 1
n //= 2
v = rho(n)
while v!=n and n>1:
ans.setdefault(v, 0)
while n%v==0:
n //= v
ans[v] += 1
if n>3 and is_prime(n):
ans.setdefault(n,0)
ans[n] += 1
return ans
v = rho(n)
if n>1:
ans.setdefault(n, 0)
ans[n] += 1
return ans
n = int(input())
m = 62
dp = dlist(m,m,m,m) # dp[v0][v][l][k] := 末尾v, 長さl, 総和k の単調非減少列の個数
for v in range(m):
dp[v][v][1][v] = 1
for v in range(m):
for l in range(1,m):
for k in range(m):
for v0 in range(m):
val = dp[v0][v][l][k]
if val==0:
continue
for nv in range(v,m):
nk = k + nv
nl = l+1
if nk>=m or nl>=m:
break
dp[v0][nv][nl][nk] += val
f = factor(n)
ks = list(f.keys())
vs = list(f.values())
from itertools import product
ans = 0
for t in product(*[range(val) for val in vs]):
# ks[i] が t[i] の状態
cur = 1
L = INF
for i in range(len(t)):
cur *= ks[i]**t[i]
if t[i]>0:
L = min(L, vs[i]//t[i])
if L==INF:
continue
for l in range(1,L+1):
res = 1
for i in range(len(t)):
tmp = 0
for vv in range(m):
tmp += dp[t[i]][vv][l][vs[i]]
res *= tmp
if res==0:
break
ans += res
print(ans+1)