結果
| 問題 |
No.2397 ω冪
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:08:28 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 5,753 bytes |
| コンパイル時間 | 303 ms |
| コンパイル使用メモリ | 82,600 KB |
| 実行使用メモリ | 68,668 KB |
| 最終ジャッジ日時 | 2025-05-14 13:10:14 |
| 合計ジャッジ時間 | 4,518 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 3 RE * 38 |
ソースコード
import sys
# Set a higher recursion depth limit to handle potentially deep recursive calls.
# The maximum length of the binary representation is 10^5. The depth of recursion might
# be related to this length, possibly linear in the worst case (e.g., N = 2^k - 1).
# A value like 2*10^5 + 100 should be safe for L=10^5.
# Use try-except block in case setting the limit fails (e.g., due to OS restrictions).
try:
sys.setrecursionlimit(2 * 10**5 + 100)
except Exception as e:
# If setting the limit fails, print a warning to stderr. The program might still work
# for smaller inputs or if the actual recursion depth is within the default limit.
print(f"Warning: Could not set high recursion depth: {e}", file=sys.stderr)
pass
# Memoization cache (dictionary) to store results of compare_int(N, M).
# Keys are tuples (N, M), values are boolean results (True if N < M, False otherwise).
memo = {}
def get_components_int(n):
"""
Computes the components (N0, N1) for a positive integer n,
where n is uniquely represented as n = (2 * N0 + 1) * 2^N1.
N1 is the exponent of 2 in the prime factorization of n (v_2(n)).
N0 = ( (n / 2^N1) - 1 ) / 2.
Assumes n > 0.
"""
# The function should not be called with n=0. The main comparison logic handles n=0 as a base case.
if n == 0:
raise ValueError("get_components_int called with 0")
# Find N1: the number of trailing zeros in the binary representation of n.
# The expression (n & -n) isolates the lowest set bit. For n > 0, this value is 2^N1.
# Example: n=12 (1100). -n is two's complement. In Python large ints it works conceptually.
# -12 is ...11110100. n & -n = 1100 & ...0100 = 0100 = 4. Value is 2^2.
lowest_set_bit = n & -n
# The bit_length() method returns the number of bits required to represent an integer in binary, excluding the sign and leading zeros.
# For a power of two, 2^k, its bit_length is k+1.
# So, N1 = bit_length(2^N1) - 1.
n1 = lowest_set_bit.bit_length() - 1
# Calculate the odd part of n: temp_n = n / 2^N1
# Right shifting by n1 performs integer division by 2^n1.
temp_n = n >> n1
# Compute N0 from the odd part temp_n. Since temp_n = 2*N0 + 1:
# N0 = (temp_n - 1) / 2
# Right shifting by 1 performs integer division by 2.
N0_val = (temp_n - 1) >> 1
# Return the computed components (N0, N1) as a tuple of integers.
return (N0_val, N1_val)
def compare_int(N, M):
"""
Recursively compares non-negative integers N and M based on the rule derived from the problem structure:
N < M if and only if the pair (N1, N0) is lexicographically smaller than (M1, M0).
Uses memoization to store results and avoid redundant computations.
"""
# Create a state tuple (N, M) to use as a key in the memoization dictionary.
state = (N, M)
# Check if the result for this state is already in the cache.
if state in memo:
return memo[state]
# Base cases for the recursion:
if N == M:
# If N equals M, then N is not strictly less than M.
result = False
elif N == 0:
# If N is 0, and M must be non-zero (since N != M), then N < M is true.
result = True
elif M == 0:
# If M is 0, and N must be non-zero (since N != M), then N < M is false.
result = False
else:
# Recursive step: Both N > 0 and M > 0.
# Compute components (N0, N1) for N and (M0, M1) for M.
N0, N1 = get_components_int(N)
M0, M1 = get_components_int(M)
# Perform lexicographical comparison of pairs (N1, N0) and (M1, M0).
# This means we compare N1 and M1 first. If they are equal, we compare N0 and M0.
# Recursively compare N1 and M1.
N1_lt_M1 = compare_int(N1, M1)
if N1_lt_M1:
# If N1 < M1, then the pair (N1, N0) is lexicographically smaller than (M1, M0).
result = True
else:
# N1 >= M1. We need to determine if N1 == M1 or N1 > M1.
# We can do this by checking the opposite comparison: M1 < N1.
# Note: `compare_int(M1, N1)` might already be computed or will be computed and memoized.
M1_lt_N1 = compare_int(M1, N1)
# If N1 is not less than M1 (N1_lt_M1 is False) AND M1 is not less than N1 (M1_lt_N1 is False),
# then N1 must be equal to M1.
if not M1_lt_N1:
# Case N1 == M1: The comparison depends on N0 and M0.
# Recursively compare N0 and M0. The result is True if N0 < M0.
result = compare_int(N0, M0)
else:
# Case N1 > M1 (since M1 < N1 is True).
# The pair (N1, N0) is lexicographically larger than (M1, M0).
result = False
# Store the computed result in the memoization cache before returning.
memo[state] = result
return result
# Main execution block: reads input, calls the comparison function, and prints the result.
if __name__ == '__main__':
# Read N and M from standard input. They are given as binary strings.
N_bin = sys.stdin.readline().strip()
M_bin = sys.stdin.readline().strip()
# Convert the binary strings to Python's arbitrary precision integers.
# Python handles large integers automatically.
N = int(N_bin, 2)
M = int(M_bin, 2)
# Call the compare_int function to determine if N < M according to the problem's logic.
if compare_int(N, M):
# If compare_int returns True, it means N < M (which corresponds to f(N) \in f(M)).
print("Yes")
else:
# Otherwise, N is not less than M.
print("No")
qwewe