結果
| 問題 | 
                            No.2829 GCD Divination
                             | 
                    
| コンテスト | |
| ユーザー | 
                             ぬるぽ
                         | 
                    
| 提出日時 | 2024-08-03 09:25:04 | 
| 言語 | PyPy3  (7.3.15)  | 
                    
| 結果 | 
                             
                                AC
                                 
                             
                            
                         | 
                    
| 実行時間 | 302 ms / 2,000 ms | 
| コード長 | 1,745 bytes | 
| コンパイル時間 | 350 ms | 
| コンパイル使用メモリ | 82,320 KB | 
| 実行使用メモリ | 92,520 KB | 
| 最終ジャッジ日時 | 2024-08-03 09:25:11 | 
| 合計ジャッジ時間 | 6,863 ms | 
| 
                            ジャッジサーバーID (参考情報)  | 
                        judge2 / judge5 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| other | AC * 35 | 
ソースコード
from copy import deepcopy, copy
import sys
import io
from typing import Optional
import time
from random import randrange, randint, random, uniform
import sys, io
from collections import deque, defaultdict
import heapq
from collections import Counter
import math
from math import gcd
from functools import lru_cache
from itertools import combinations, permutations
from bisect import bisect_left, bisect_right
from itertools import groupby
from itertools import accumulate
from math import factorial
import decimal
import math
# from sortedcontainers import SortedList
# import pypyjit
# pypyjit.set_param("max_unroll_recursion=-1")
sys.setrecursionlimit(1000000000)
sys.set_int_max_str_digits(1000000000)
start_time = time.time()
N = int(input())
def divisor(n) -> list:
    sq = n**0.5
    border = int(sq)
    table = []
    bigs = []
    for small in range(1, border + 1):
        if n % small == 0:
            table.append(small)
            big = n // small
            bigs.append(big)
    if border == sq:  # nが平方数
        bigs.pop()
    table += reversed(bigs)
    return table
divs = divisor(N)
divs = sorted(divs)
dp = defaultdict(int)
for i in range(len(divs)):
    n = divs[i]
    if n == 1:
        continue
    divs_now = divisor(n)
    divs_now = list(reversed(sorted(divs_now)))
    counter = defaultdict(int)
    for j in range(len(divs_now)):
        counter[divs_now[j]] += n // divs_now[j]
        for k in range(j):
            if divs_now[k] % divs_now[j] == 0:
                counter[divs_now[j]] -= counter[divs_now[k]]
    for num in counter:
        if num == n:
            continue
        dp[n] += 1 / n * counter[num] * dp[num]
    dp[n] += 1
    dp[n] *= (n) / (n - 1)
print(dp[N])
            
            
            
        
            
ぬるぽ