結果
| 問題 |
No.3364 Push_back Operation
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-10-25 16:39:42 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 678 ms / 2,000 ms |
| コード長 | 2,488 bytes |
| コンパイル時間 | 422 ms |
| コンパイル使用メモリ | 82,908 KB |
| 実行使用メモリ | 67,308 KB |
| 最終ジャッジ日時 | 2025-11-17 20:31:27 |
| 合計ジャッジ時間 | 15,711 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 53 |
ソースコード
# 法 (mod)
big2 = 998244353
def simple(n):
"""
O(N * logN) のナイーブな実装 (C++の simple 関数に相当)
sum_{i=1}^{n} (floor(n/i))^i
"""
ans = 0
for i in range(1, n + 1):
k = n // i
# k^i % big2 を計算
term = pow(k, i, big2)
ans = (ans + term) % big2
return ans
def nosimple(n):
"""
O(sqrt(N) * logN) の高速な実装 (C++の nosimple 関数に相当)
"""
ans = 0
temp = n # 第2ループの上限 (n // (i+1) で更新)
# --- 第1ループ (i*i <= n の範囲) ---
# floor(n/i) の値が k (k <= sqrt(N)) となる i の区間についてまとめて計算
i = 1
while i * i <= n:
k = i # C++コードのループ変数 i を k (底) と読み替える
up = n // k # floor(n/i)=k となる最大の i
down = n // (k + 1) # floor(n/i)=k となる最小の i の一つ手前
# 計算対象: sum_{j=down+1}^{up} k^j
if k == 1:
# k=1 (公比が1) の場合
# 1 を (up - down) 回足す
ans = (ans + (up - down)) % big2
else:
# k > 1 (等比数列の和の公式)
# 初項 a = k^(down + 1)
a = pow(k, down + 1, big2)
# 項数 num = up - down
num_terms = up - down
# 公比の項 b = k^num
b = pow(k, num_terms, big2)
# (k-1) の逆元 (フェルマーの小定理)
# C++の (/(i-1)) に相当
inv_k_minus_1 = pow(k - 1, big2 - 2, big2)
# a * (b - 1) * (k - 1)^-1
term = (b - 1 + big2) % big2 # (b - 1)
term = (term * inv_k_minus_1) % big2 # * (k - 1)^-1
term = (a * term) % big2 # * a
ans = (ans + term) % big2
temp = down
i += 1
# --- 第2ループ (i が 1 から temp (約sqrt(N)) まで) ---
# floor(n/i) の値が k (k > sqrt(N)) となる i について計算
for i in range(1, temp + 1):
k = n // i # 底
# (n/i)^i % big2
term = pow(k, i, big2)
ans = (ans + term) % big2
return ans
# --- メイン処理 (C++の main 関数に相当) ---
if __name__ == "__main__":
N = int(input())
# C++のmain関数は nosimple のみを呼び出している
print(nosimple(N))