結果
問題 |
No.2281 K → K-1 01 Flip
|
ユーザー |
![]() |
提出日時 | 2025-03-31 17:56:24 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,704 bytes |
コンパイル時間 | 329 ms |
コンパイル使用メモリ | 82,088 KB |
実行使用メモリ | 52,736 KB |
最終ジャッジ日時 | 2025-03-31 17:57:53 |
合計ジャッジ時間 | 8,577 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | TLE * 1 -- * 55 |
ソースコード
import sys def main(): import sys input = sys.stdin.read data = input().split() idx = 0 N = int(data[idx]) idx +=1 Q = int(data[idx]) idx +=1 S = data[idx] idx +=1 # Preprocess the original runs: list of (pos, char) runs = [] if N ==0: pass else: current_char = S[0] current_len =1 for c in S[1:]: if c == current_char: current_len +=1 else: runs.append( (current_len, current_char) ) current_char = c current_len =1 runs.append( (current_len, current_char) ) # Precompute the prefix sums and run starts prefix = [0]*(len(runs)+1) for i in range(len(runs)): prefix[i+1] = prefix[i] + runs[i][0] run_starts = [0]*(len(runs)+1) for i in range(len(runs)): run_starts[i+1] = run_starts[i] + runs[i][0] for _ in range(Q): L = int(data[idx])-1 # 0-based idx +=1 R = int(data[idx])-1 # 0-based [inclusive] idx +=1 K = int(data[idx]) idx +=1 # Find the runs that intersect with the substring [L, R] (0-based) # Find the first run that has start >= L, using binary search # run_starts is the prefix sum of run lengths. Find the largest i where run_starts[i] <= L left = 0 right = len(run_starts)-1 start_run = 0 while left <= right: mid = (left+right)//2 if run_starts[mid] <= L: start_run = mid left = mid +1 else: right = mid-1 # the first run is start_run current_run_start = start_run total_length = R - L +1 current_runs = [] accumulated = run_starts[start_run] while current_run_start < len(runs): run_len, run_char = runs[current_run_start] run_end = accumulated + run_len -1 seg_start = max(L, accumulated) seg_end = min(R, run_end) if seg_start > seg_end: break current_runs.append( (seg_end - seg_start +1, run_char) ) accumulated += run_len current_run_start +=1 # Now process current_runs # Simulate the operations stack = [] for l, c in current_runs: if stack and stack[-1][1] == c: stack[-1] = (stack[-1][0] + l, c) else: stack.append( (l, c) ) # After merging, check if can apply operations while True: # Check the last element of stack if len(stack) <1: break cl, cc = stack[-1] if cl < K: break # We can apply at least one operation ops = cl // K total_ops = ops new_l = cl % K replace_l = ops * (K-1) replace_c = '1' if cc == '0' else '0' stack.pop() if new_l >0: if stack and stack[-1][1] == cc: stack[-1] = (stack[-1][0] + new_l, cc) else: stack.append( (new_l, cc) ) if replace_l >0: if stack and stack[-1][1] == replace_c: stack[-1] = (stack[-1][0] + replace_l, replace_c) else: stack.append( (replace_l, replace_c) ) # Check if after replacement, we can apply more operations while True: changed = False # Check the new element if len(stack)>=1: nl, nc = stack[-1] if nc == replace_c: if nl >= K: ops = nl // K total_ops += ops new_l = nl % K stack.pop() replace_l = ops * (K-1) replace_c = '1' if nc == '0' else '0' if new_l >0: if stack and stack[-1][1] == nc: stack[-1] = (stack[-1][0] + new_l, nc) else: stack.append( (new_l, nc) ) if replace_l >0: if stack and stack[-1][1] == replace_c: stack[-1] = (stack[-1][0] + replace_l, replace_c) else: stack.append( (replace_l, replace_c) ) changed = True nc = replace_c while len(stack)>=2: a_l, a_c = stack[-2] b_l, b_c = stack[-1] if a_c == b_c: stack.pop() stack[-1] = (a_l + b_l, a_c) if stack[-1][0] >= K: changed = True break else: break if not changed: break # The total length is the sum of the stack min_length = sum( l for l, c in stack ) print( min_length ) if __name__ == "__main__": main()