結果
問題 |
No.1036 Make One With GCD 2
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:14:06 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 6,594 bytes |
コンパイル時間 | 319 ms |
コンパイル使用メモリ | 82,688 KB |
実行使用メモリ | 179,244 KB |
最終ジャッジ日時 | 2025-05-14 13:15:29 |
合計ジャッジ時間 | 22,818 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 34 TLE * 1 -- * 6 |
ソースコード
import math import sys # Utilize math.gcd for efficient Greatest Common Divisor calculation. # Python's built-in math.gcd is implemented in C and is generally fast. # It handles large integers automatically due to Python's arbitrary precision integers. def solve(): # Read input N, the number of elements in the array. # Use sys.stdin.readline for faster input reading compared to input(). N = int(sys.stdin.readline()) # Read the array elements A_1, A_2, ..., A_N. # Map the string inputs to integers. A = list(map(int, sys.stdin.readline().split())) # Initialize the total count of contiguous subarrays whose GCD is 1. total_count = 0 # `current_gcd_info` stores information about GCDs of subarrays ending at the previous index (r-1). # It is a list of tuples `(k, g)`. # `k` is the starting index (0-based) of a contiguous range of starting positions. # `g` is the GCD of subarrays `A[l...r-1]` for all `l` starting from `k` up to the start of the next range. # Specifically, `k` is the *leftmost* starting index such that `gcd(A[k...r-1]) = g`. # The list is maintained sorted by `k` in increasing order. # The number of pairs in this list is bounded by O(log(max(A_i))). current_gcd_info = [] # Iterate through the array A with index `r` from 0 to N-1. # In each iteration, `r` represents the right endpoint of the contiguous subarrays being considered. for r in range(N): # `new_gcd_info_temp` will store candidate pairs `(k, g)` for subarrays ending at the current index `r`. # `g = gcd(A[k...r])`. new_gcd_info_temp = [] # Step 1: Consider the subarray containing only the element A[r]. # This subarray starts at index `r` and ends at index `r`. Its GCD is A[r]. # Add this base case pair `(r, A[r])` to the temporary list. new_gcd_info_temp.append((r, A[r])) # Step 2: Update the GCD information from the previous step (subarrays ending at r-1). # For each pair `(k, g)` in `current_gcd_info`, where `g = gcd(A[k...r-1])`, # we compute the GCD for the extended subarray `A[k...r]`. # This new GCD is `gcd(g, A[r])`. for k, g in current_gcd_info: # Calculate the new GCD value. new_g = math.gcd(g, A[r]) # Add the updated pair `(k, new_g)` to the temporary list. new_gcd_info_temp.append((k, new_g)) # Step 3: Merge the generated candidate pairs to maintain the required properties. # The temporary list `new_gcd_info_temp` might contain multiple pairs with the same GCD value `g`, # or pairs where `g` is the same as the GCD of a range starting further left. # We need to keep only the distinct GCD values `g`, associated with their *leftmost* starting index `k`. # First, sort the temporary list by starting index `k`. This makes merging easier. # The size of this list is O(log(max(A_i))), so sorting is fast: O(log(max A_i) * log(log(max A_i))). new_gcd_info_temp.sort(key=lambda x: x[0]) # Perform the merge operation. merged_gcd_info = [] if new_gcd_info_temp: # Proceed only if the list is not empty. # Add the first pair (the one with the smallest `k`) unconditionally. merged_gcd_info.append(new_gcd_info_temp[0]) # Keep track of the GCD value `g` of the last pair added to `merged_gcd_info`. last_g = new_gcd_info_temp[0][1] # Iterate through the rest of the sorted temporary pairs. for i in range(1, len(new_gcd_info_temp)): k, g = new_gcd_info_temp[i] # If the current GCD `g` is different from the `last_g`, it means this pair # starts a new distinct GCD value range. Add it to `merged_gcd_info`. if g != last_g: merged_gcd_info.append((k, g)) # Update `last_g` to the current GCD `g`. last_g = g # If `g == last_g`, this pair `(k, g)` is redundant. The previously added pair # in `merged_gcd_info` already covers this GCD value `g` starting from an earlier # index (`last_k <= k`). We only want the pair with the minimum `k`, so we skip this one. # Update `current_gcd_info` to be the `merged_gcd_info` for the next iteration (r+1). current_gcd_info = merged_gcd_info # Step 4: Calculate the contribution to the `total_count` from subarrays ending at index `r`. # Iterate through the finalized `current_gcd_info` list for index `r`. num_pairs = len(current_gcd_info) for i in range(num_pairs): # Get the starting index `k_i` and GCD value `g_i` for the i-th range. k_i, g_i = current_gcd_info[i] # We are only interested in subarrays whose GCD is 1. if g_i == 1: # If the GCD is 1, this pair `(k_i, 1)` indicates that `gcd(A[l...r]) = 1` # for all starting indices `l` within a certain range `[k_i, end_l]`. # Determine the end index `end_l` of this range. if i + 1 < num_pairs: # If there is a next pair `(k_{i+1}, g_{i+1})`, the current range of `l` # ends just before the start of the next range, i.e., at `k_{i+1} - 1`. k_next = current_gcd_info[i+1][0] end_l = k_next - 1 else: # If this is the last pair in `current_gcd_info`, the range of `l` # extends up to the current endpoint `r`. end_l = r # The number of valid starting indices `l` in the interval `[k_i, end_l]` is `end_l - k_i + 1`. # Each such `l` corresponds to a subarray `A[l...r]` with GCD 1. num_subarrays = end_l - k_i + 1 # Add this count to the total count. total_count += num_subarrays # After iterating through all possible right endpoints `r`, `total_count` holds the final answer. # Print the total count. Use `sys.stdout.write` and `str()` conversion for potentially faster output. # Adding a newline character as required by the problem statement. sys.stdout.write(str(total_count) + '\n') # Call the main function to solve the problem when the script is executed. if __name__ == '__main__': solve()