結果
| 問題 |
No.1611 Minimum Multiple with Double Divisors
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:19:41 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 6,968 bytes |
| コンパイル時間 | 280 ms |
| コンパイル使用メモリ | 82,796 KB |
| 実行使用メモリ | 86,656 KB |
| 最終ジャッジ日時 | 2025-05-14 13:20:55 |
| 合計ジャッジ時間 | 7,980 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 2 |
| other | AC * 1 WA * 10 TLE * 1 -- * 25 |
ソースコード
import sys
import math
# Function to generate primes up to n using Sieve of Eratosthenes
def get_primes(n):
"""
Generates a list of prime numbers up to n using the Sieve of Eratosthenes.
"""
primes = []
is_prime = [True] * (n + 1)
# 0 and 1 are not prime
if n >= 0: is_prime[0] = False
if n >= 1: is_prime[1] = False
for p in range(2, n + 1):
if is_prime[p]:
primes.append(p)
# Mark multiples of p as not prime. Start from p*p for optimization.
for i in range(p * p, n + 1, p):
is_prime[i] = False
return primes
# Function to find the prime factorization of a number n
# Uses the precomputed list of primes for trial division up to sqrt(n)
def get_prime_factorization_optimized(n, primes_list):
"""
Finds the prime factorization of n using trial division with precomputed primes.
Returns a dictionary where keys are prime factors and values are their exponents.
"""
factors = {}
temp_n = n
idx = 0
# Iterate through the precomputed primes list
while idx < len(primes_list):
p = primes_list[idx]
# Optimization: If p*p > temp_n, then the current temp_n must be prime
# because all smaller potential prime factors have already been divided out.
# Using p > temp_n // p check to avoid potential overflow for large p, although p*p fits 64-bit for p up to ~3e9.
# The condition p*p > temp_n is safe for p <= sqrt(10^11).
if p * p > temp_n:
break
# If p divides temp_n, find its exponent
if temp_n % p == 0:
count = 0
while temp_n % p == 0:
count += 1
temp_n //= p
factors[p] = count
# Optimization: if temp_n becomes 1, factorization is complete.
if temp_n == 1:
break
idx += 1 # Move to the next prime in the list
# If temp_n > 1 after the loop, the remaining temp_n is a prime factor itself.
# This can happen if n has a large prime factor > sqrt(n).
if temp_n > 1:
# Add this large prime factor to the dictionary.
# The exponent must be 1 because if it were higher (e.g., temp_n = P^k with k>=2),
# then P <= sqrt(temp_n), and P should have been found during the loop.
factors[temp_n] = factors.get(temp_n, 0) + 1
return factors
# Function to find the smallest prime number that is NOT a factor of X
# factors_map contains the prime factorization of X
def find_smallest_missing_prime(factors_map, primes_list):
"""
Finds the smallest prime from primes_list that is not a key in factors_map.
"""
for p in primes_list:
# The first prime encountered that is not in the keys of factors_map is the smallest missing prime.
if p not in factors_map:
return p
# This part should theoretically not be reached for X <= 10^11.
# The product of the first few primes grows very quickly.
# Product of primes up to 31 exceeds 10^11.
# So the smallest missing prime (q_min) must be <= 37.
# The precomputed primes list extends far beyond this.
return -1 # Should indicate an error or unexpected situation
# Main logic to solve the problem for a single test case X
def solve(primes_list):
"""
Solves the problem for a single value X, given the list of precomputed primes.
Prints the minimum Y satisfying the conditions.
"""
X = int(sys.stdin.readline())
# Handle the base case X = 1 separately.
# tau(1) = 1. We need Y with tau(Y) = 2*1 = 2.
# Smallest number with 2 divisors is the smallest prime, 2.
# Y must be a multiple of X=1 (always true). Minimum Y is 2.
if X == 1:
print(2)
return
# Get the prime factorization of X
factors = get_prime_factorization_optimized(X, primes_list)
# Initialize min_Y to -1, representing infinity or uninitialized state.
min_Y = -1
# Explore candidates for Y based on modifying existing prime factors of X (Case 1)
# Candidate Type 1.1: Increase the exponent of one prime factor p_j by (a_j+1).
# Y_j = X * p_j^(a_j+1) results in Y_j = p_1^a_1 ... p_j^(a_j + (a_j+1)) ... p_k^a_k = p_1^a_1 ... p_j^(2a_j+1) ... p_k^a_k
# tau(Y_j) = (a_1+1)...(2a_j+1+1)...(a_k+1) = (a_1+1)...(2(a_j+1))...(a_k+1) = 2 * tau(X)
for p, a in factors.items():
# Calculate p^(a+1). Python handles large integers.
pk_power = pow(p, a + 1)
# Calculate the candidate Y = X * p^(a+1)
candidate_Y = X * pk_power
# Update min_Y if this candidate is smaller than the current minimum
if min_Y == -1 or candidate_Y < min_Y:
min_Y = candidate_Y
# Candidate Type 1.2 (Special Case): If X has exactly two prime factors p1, p2
# with exponents (1, 2) or (2, 1).
# In this case, Y = X * p1 * p2 is also a valid candidate.
# Y = p1^(a1+1) * p2^(a2+1) * ...
# tau(Y) = (a1+1+1)(a2+1+1)... = (a1+2)(a2+2)...
# We need tau(Y) = 2*tau(X). This simplifies to (a1+2)(a2+2) = 2(a1+1)(a2+1).
# This equality holds only if (a1, a2) is (1, 2) or (2, 1).
if len(factors) == 2:
p_list = list(factors.keys())
p1 = p_list[0]
p2 = p_list[1]
a1 = factors[p1]
a2 = factors[p2]
# Check if exponents match the special case condition
if (a1 == 1 and a2 == 2) or (a1 == 2 and a2 == 1):
# Calculate the special candidate Y = X * p1 * p2
candidate_Y = X * p1 * p2
# Update min_Y if this candidate is smaller
if min_Y == -1 or candidate_Y < min_Y:
min_Y = candidate_Y
# Explore candidates for Y based on introducing a new prime factor (Case 2)
# We need tau(Y) = 2 * tau(X). If Y = X * q^c, tau(Y) = tau(X) * (c+1).
# So c+1 = 2, which means c=1. Y = X * q.
# To minimize Y, we must choose the smallest prime q (denoted q_min) that does not divide X.
# Find the smallest prime q_min not in the factors of X
q_min = find_smallest_missing_prime(factors, primes_list)
# Calculate the candidate Y = X * q_min
candidate_Y_new = X * q_min
# Update min_Y if this candidate is smaller
if min_Y == -1 or candidate_Y_new < min_Y:
min_Y = candidate_Y_new
# Print the overall minimum Y found across all candidates
print(min_Y)
# === Main Execution ===
# Precompute primes up to sqrt(Maximum X value) + a small buffer.
MAX_X = 10**11
# Calculate the integer part of sqrt(10^11)
MAX_PRIME_CHECK = int(math.sqrt(MAX_X)) + 2 # A limit slightly above the square root
# Generate primes using the Sieve
primes = get_primes(MAX_PRIME_CHECK)
# Read the number of test cases
T = int(sys.stdin.readline())
# Process each test case
for _ in range(T):
solve(primes) # Pass the precomputed primes list to the solver function
qwewe