結果
問題 | No.2121 帰属関係と充足可能性 |
ユーザー |
![]() |
提出日時 | 2025-05-14 13:19:12 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 303 ms / 2,000 ms |
コード長 | 8,467 bytes |
コンパイル時間 | 428 ms |
コンパイル使用メモリ | 83,028 KB |
実行使用メモリ | 129,756 KB |
最終ジャッジ日時 | 2025-05-14 13:20:03 |
合計ジャッジ時間 | 4,312 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 49 |
ソースコード
import sys # Increase recursion depth if necessary, though the iterative generation should avoid deep recursion. # sys.setrecursionlimit(2000) def solve(): N = int(sys.stdin.readline()) A = list(map(int, sys.stdin.readline().split())) A0, A1, A2, A3, A4, A5 = A # Handle N=0 case: V_0 is the empty set, so no elements m_0, m_1, m_2 exist. if N == 0: print("NO") return # Check for conditions that violate the Axiom of Regularity (no set contains itself). # In the context of Von Neumann hierarchy V_N, sets are well-founded, so x \in x is impossible. # Condition 2: m_{A1} \in m_{A2}. If A1 == A2, this becomes m_{A1} \in m_{A1}, which is impossible. # Condition 3: m_{A3} \in m_{A2}. If A3 == A2, this becomes m_{A2} \in m_{A2} (since m_{A3}=m_{A2}), impossible. # Condition 4: m_{A4} \in m_{A2}. If A4 == A2, this becomes m_{A2} \in m_{A2}, impossible. # Condition 5: m_{A5} \in m_{A0}. If A5 == A0, this becomes m_{A0} \in m_{A0}, impossible. if A5 == A0 or A1 == A2 or A3 == A2 or A4 == A2: print("NO") return # Generate the hierarchy of sets V_k up to V_N. # We assign a unique integer ID to each distinct set encountered. # `all_sets` list stores the canonical representation (sorted tuple of element IDs) for each set ID. # ID 0 is reserved for the empty set. all_sets = [()] # `set_to_id` dictionary maps canonical representation (tuple) to the assigned set ID. set_to_id = {(): 0} next_id = 1 # `V_k_ids` list of lists stores the IDs of sets belonging to each V_k. V_k_ids = [[] for _ in range(N + 1)] # V_0 is the empty set, has no elements. Its list of IDs is empty. V_k_ids[0] = [] # V_1 = {emptyset}. The empty set has ID 0. empty_set_id = 0 if N >= 1: V_k_ids[1] = [empty_set_id] # Generate V_k for k=1..N iteratively. # V_k is the power set of V_{k-1}. for k in range(1, N + 1): # Get the list of IDs of elements in V_{k-1} elements_of_V_k_minus_1_ids = V_k_ids[k-1] num_elements_V_k_minus_1 = len(elements_of_V_k_minus_1_ids) # Store IDs of sets that constitute V_k current_V_k_ids = [] # Iterate through all possible subsets of V_{k-1} using bitmasks. # Each integer `i` from 0 to 2^|V_{k-1}| - 1 represents a subset. limit = 1 << num_elements_V_k_minus_1 for i in range(limit): # Construct the current subset based on the bits of `i`. subset_element_ids = [] for j in range(num_elements_V_k_minus_1): if (i >> j) & 1: # If j-th bit is set, include the j-th element of V_{k-1} in the subset. subset_element_ids.append(elements_of_V_k_minus_1_ids[j]) # Use a sorted tuple of element IDs as the canonical representation for the set. subset_element_ids.sort() canon_rep = tuple(subset_element_ids) set_id = -1 # Check if this set structure has been seen before. if canon_rep in set_to_id: set_id = set_to_id[canon_rep] else: # Assign a new ID if it's a new set structure. set_id = next_id set_to_id[canon_rep] = set_id all_sets.append(canon_rep) next_id += 1 # Add the ID of this set to the list for V_k. current_V_k_ids.append(set_id) # Store the generated IDs for V_k. Sorting is optional but helps consistency. V_k_ids[k] = sorted(current_V_k_ids) # Finished generating sets up to V_N. # Get the list of IDs for elements in V_N. V_N_element_ids = V_k_ids[N] # It's possible V_N is empty only if N=0, which is handled already. # If N > 0, V_N always contains at least the empty set. # Create a set of IDs for elements in V_{N-1} for efficient lookups. ids_V_N_minus_1_set = set(V_k_ids[N-1]) # Determine which variables (m_0, m_1, m_2) MUST be assigned values from V_{N-1}. # This is required by the membership conditions: if `m_X \in m_Y`, then `m_X` must be an element of `V_{N-1}` # because `m_Y \in V_N` implies `m_Y \subseteq V_{N-1}`. restricted_vars_flags = [False, False, False] # Condition 2: m_{A1} \in m_{A2}. Implies m_{A1} must be a set from V_{N-1}. The variable m_{A1} is restricted. restricted_vars_flags[A1] = True # Condition 3: m_{A3} \in m_{A2}. Implies m_{A3} must be a set from V_{N-1}. The variable m_{A3} is restricted. restricted_vars_flags[A3] = True # Condition 4: m_{A4} \in m_{A2}. Implies m_{A4} must be a set from V_{N-1}. The variable m_{A4} is restricted. restricted_vars_flags[A4] = True # Condition 5: m_{A5} \in m_{A0}. Implies m_{A5} must be a set from V_{N-1}. The variable m_{A5} is restricted. restricted_vars_flags[A5] = True # Define the possible choices (domain) for each variable m_0, m_1, m_2. # Initially, assume all elements of V_N are possible choices. choice_sets = [list(V_N_element_ids) for _ in range(3)] # Apply restrictions based on `restricted_vars_flags`. for i in range(3): if restricted_vars_flags[i]: # If m_i is restricted, filter its choice set to include only IDs that are also in V_{N-1}. choice_sets[i] = [id_val for id_val in choice_sets[i] if id_val in ids_V_N_minus_1_set] # Precompute Python set objects for each set ID for faster subset and membership checks. # `all_sets[i]` is a tuple representing the elements (by ID) of the set with ID `i`. # `all_sets_as_python_sets[i]` is the corresponding Python set object. all_sets_as_python_sets = { i : set(all_sets[i]) for i in range(len(all_sets)) } # If any choice set becomes empty after applying restrictions, no solution is possible. if not choice_sets[0] or not choice_sets[1] or not choice_sets[2]: print("NO") return # Iterate through the restricted search space for assignments (id_0, id_1, id_2). # This significantly reduces the number of checks compared to |V_N|^3 for large N. for id_0 in choice_sets[0]: for id_1 in choice_sets[1]: for id_2 in choice_sets[2]: # Current assignment: m_0 has ID id_0, m_1 has ID id_1, m_2 has ID id_2. ids = [id_0, id_1, id_2] # Map the A_k indices to the actual IDs based on the current assignment. id_A0 = ids[A0] id_A1 = ids[A1] id_A2 = ids[A2] id_A3 = ids[A3] id_A4 = ids[A4] id_A5 = ids[A5] # Retrieve the precomputed Python set objects for the relevant IDs. set_A0 = all_sets_as_python_sets[id_A0] set_A1 = all_sets_as_python_sets[id_A1] set_A2 = all_sets_as_python_sets[id_A2] # Check the 5 conditions of the formula: # Condition 1: m_{A0} \subseteq m_{A1} # Check if the set represented by id_A0 is a subset of the set represented by id_A1. if not set_A0.issubset(set_A1): continue # If condition fails, try next assignment. # Condition 2: m_{A1} \in m_{A2} # Check if the ID representing set m_{A1} (which is id_A1) is an element of the set m_{A2}. # `set_A2` contains the IDs of elements constituting the set m_{A2}. if id_A1 not in set_A2: continue # Condition 3: m_{A3} \in m_{A2} if id_A3 not in set_A2: continue # Condition 4: m_{A4} \in m_{A2} if id_A4 not in set_A2: continue # Condition 5: m_{A5} \in m_{A0} if id_A5 not in set_A0: # `set_A0` contains IDs of elements of m_{A0}. continue # If all 5 conditions are satisfied for this triple (id_0, id_1, id_2). print("YES") return # Found a satisfying assignment, exit. # If the loops complete without finding any satisfying assignment. print("NO") # Execute the solver function. solve()