結果

問題 No.2798 Multiple Chain
ユーザー navel_tosnavel_tos
提出日時 2024-06-28 23:11:17
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 60 ms / 2,000 ms
コード長 3,139 bytes
コンパイル時間 196 ms
コンパイル使用メモリ 82,176 KB
実行使用メモリ 68,608 KB
最終ジャッジ日時 2024-06-28 23:11:22
合計ジャッジ時間 4,257 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 49 ms
61,440 KB
testcase_01 AC 49 ms
61,440 KB
testcase_02 AC 48 ms
61,696 KB
testcase_03 AC 47 ms
61,312 KB
testcase_04 AC 47 ms
61,312 KB
testcase_05 AC 48 ms
61,312 KB
testcase_06 AC 50 ms
61,696 KB
testcase_07 AC 49 ms
60,928 KB
testcase_08 AC 49 ms
61,568 KB
testcase_09 AC 47 ms
61,184 KB
testcase_10 AC 47 ms
61,440 KB
testcase_11 AC 50 ms
61,440 KB
testcase_12 AC 54 ms
61,056 KB
testcase_13 AC 49 ms
61,312 KB
testcase_14 AC 49 ms
61,440 KB
testcase_15 AC 48 ms
61,568 KB
testcase_16 AC 47 ms
61,824 KB
testcase_17 AC 49 ms
61,440 KB
testcase_18 AC 50 ms
61,696 KB
testcase_19 AC 55 ms
61,952 KB
testcase_20 AC 50 ms
61,696 KB
testcase_21 AC 49 ms
61,312 KB
testcase_22 AC 48 ms
61,568 KB
testcase_23 AC 50 ms
61,184 KB
testcase_24 AC 49 ms
61,440 KB
testcase_25 AC 49 ms
61,824 KB
testcase_26 AC 47 ms
61,696 KB
testcase_27 AC 43 ms
61,568 KB
testcase_28 AC 43 ms
61,568 KB
testcase_29 AC 44 ms
61,312 KB
testcase_30 AC 45 ms
61,440 KB
testcase_31 AC 49 ms
61,184 KB
testcase_32 AC 60 ms
68,608 KB
testcase_33 AC 54 ms
65,140 KB
testcase_34 AC 58 ms
66,176 KB
testcase_35 AC 48 ms
61,824 KB
testcase_36 AC 50 ms
62,208 KB
testcase_37 AC 49 ms
61,568 KB
testcase_38 AC 57 ms
62,080 KB
testcase_39 AC 50 ms
61,740 KB
testcase_40 AC 49 ms
61,568 KB
testcase_41 AC 49 ms
61,440 KB
testcase_42 AC 49 ms
61,312 KB
testcase_43 AC 49 ms
61,440 KB
testcase_44 AC 49 ms
61,312 KB
testcase_45 AC 48 ms
61,056 KB
testcase_46 AC 47 ms
61,568 KB
testcase_47 AC 46 ms
61,568 KB
testcase_48 AC 47 ms
61,568 KB
testcase_49 AC 50 ms
61,568 KB
testcase_50 AC 48 ms
61,184 KB
testcase_51 AC 47 ms
61,184 KB
testcase_52 AC 52 ms
63,872 KB
testcase_53 AC 49 ms
61,312 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#yukicoder 2798 Multiple Chain

#O(N ^ {1/4}) 高速素因数分解
def fast_fact(N):
    import random
    gcd = lambda x,y: gcd(y, x % y) if y else abs(x)

    #Miller-Rabin Primality Test  O(logN) time, wrong rate: under 1/4 per test.
    def check_prime(n):
        if n == 1 or n % 2 == 0: return True if n == 2 else False
        m = n - 1; s = (m & -m).bit_length() - 1; d = m // pow(2, s)  #m = d * 2^s 
        if n < 48781 * 97561: test_number = [2, 7, 61]
        else: test_number = [2, 325, 9375, 28178, 450775, 9780504, 1795265022]
        if n > pow(2, 64): test_number.extend([random.randint(3, m) for _ in range(10)])
        for a in test_number:
            x, r = pow(a, d, n), 0
            if a == n or x == 1: continue
            while x != m:
                x, r = pow(x, 2, n), r + 1
                if x == 1 or r == s: return False
        return True

    #Pollards rho algorithm
    def find_prime(n):
        if n % 2 == 0: return 2
        m = int(n ** 0.125) + 1
        for c in range(1, n):
            f, x, y, k, g, q, r = lambda x: (pow(x, 2, n) + c) % n, 0, 0, 0, 1, 1, 1
            while g == 1:  #y = f^k(c), x = f^{r/2}(c).  especially, r is power of 2
                while k < 3 * r // 4: y, k = f(y), k + 1  #skip calculate
                while k < r and g == 1:
                    s = y
                    for _ in range(min(m, r - k)): y = f(y); q = q * abs(x - y) % n
                    g, k = gcd(q, n), k + m
                k, r, x = r, r * 2, y
            if g == n:  #backtrack
                g, y = 1, s
                while g == 1: y = f(y); g = gcd(abs(x - y), n)
            if g == n: continue
            return g if check_prime(g) else n//g if check_prime(n//g) else find_prime(g)
        return n  #RE prevention
                    
    A = []
    while not check_prime(N) and N > 1:
        P, E = find_prime(N), 0
        while N % P == 0: N, E = N // P, E + 1
        A.append((P, E))
    if N > 1: A.append((N, 1))
    return sorted(A)


#入力受取
N = int(input())

#素因数分解  因数の個数を列挙
P = fast_fact(N)
Q = sorted(e for f, e in P)
R = max(Q)

#分割数を考える
#DP[n][k]: 自然数nをk個の「非負整数」の和として表す場合の数
#これは蟻本式DPでO(n^2)  DP[n][k] = DP[n][k - 1] + DP[n - k][k]
#k個のなかに0を含むものはDP[n][k - 1]通り
#k個のなかに0を含まないものはDP[n - k][k]通り
DP = [[0] * 64 for _ in range(64)]
for k in range(64):
    DP[0][k] = 1
for n in range(1, 64):
    for k in range(1, 64):
        DP[n][k] = DP[n][k - 1]
        if n >= k: DP[n][k] += DP[n - k][k]

#長さxの数列であって、分割を満たすものの個数。ただし、全要素の先頭が0ではだめ。
def solve(x):
    #1. 全要素を長さxに分割する場合の数の積を求める
    ans = 1
    for q in Q:
        ans *= DP[q][x]

    #2. 全要素の先頭が0であるものの個数を求める
    if x == 1:
        return ans
    cnt = 1
    for q in Q:
        cnt *= DP[q][x - 1]
    return ans - cnt

ans = 0
for x in range(1, R + 1):
    ans += solve(x)
print(ans)
0