公式

C - 照明の切り替え / Switching the Lights 解説 by admin

Qwen3-Coder-480B

Overview

In this problem, you need to determine whether specific points (meeting rooms) are ultimately ON after performing multiple toggle (flip) operations on intervals.

Approach

As a naive approach, we could consider updating the lighting state of all rooms in the interval \([L, R]\) for each operation, but since \(N\) can be up to \(10^9\) and there can be up to \(Q = 2 \times 10^5\) operations, this would be \(O(NQ)\) overall, which is too slow.

The key observation is that only “how many times each room has been toggled” matters for the final state. That is, if a room is toggled an even number of times it remains OFF, and if toggled an odd number of times it becomes ON.

Therefore, we use the imos method (difference array technique), which efficiently handles addition over intervals. Using the imos method, we record “+1” and “-1” events for each interval, and then take the prefix sum at the end to obtain the number of toggles at each point.

Additionally, since \(N\) is very large, it is impossible to manage all rooms explicitly. However, the only positions we need to focus on are the meeting room positions \(B_i\) and the interval endpoints \(L_i, R_i+1\). Therefore, we apply coordinate compression to these values so that we only handle the necessary points.

In summary: - Each operation adds to the toggle count over an interval → speed up with the imos method - Use coordinate compression to handle the large \(N\) - Finally, check each meeting room’s position to determine whether its toggle count is odd

Algorithm

  1. For each operation interval \([L_i, R_i]\), register imos events \((L_i, +1),\ (R_i+1, -1)\).
  2. Collect all relevant points (meeting room positions \(B_i\) and event positions), sort them, and perform coordinate compression on them.
  3. Using the imos method, compute the prefix sum of toggle counts at each compressed index.
  4. For each meeting room \(B_i\), find the corresponding compressed index and determine that the room is lit if the toggle count at that position is odd.
  5. Count and output the number of lit meeting rooms.

For example, if the operations are [1, 3] and [2, 4], and the meeting room is at 2: - Events: (1,+1), (4,-1), (2,+1), (5,-1) - Compressed points: [1,2,4,5] - After imos array processing, the toggle count at position 2 is 2 → OFF

Complexity

  • Time complexity: \(O((M + Q) \log (M + Q))\)
    • Dominated by sorting events and coordinate compression
  • Space complexity: \(O(M + Q)\)
    • Size of the coordinate list and imos array

Implementation Notes

  • When using the imos method, don’t forget to place -1 at the position right after the end of the interval

  • For coordinate compression, it is efficient to remove duplicates using a set before sorting

  • When finding the index corresponding to each meeting room’s position, use bisect_right(points, b) - 1 to get the exact location

    Source Code

import sys
from bisect import bisect_left, bisect_right

def main():
    import sys
    input = sys.stdin.read
    data = input().split()
    
    idx = 0
    N = int(data[idx]); idx += 1
    M = int(data[idx]); idx += 1
    Q = int(data[idx]); idx += 1
    
    B = list(map(int, data[idx:idx+M])); idx += M
    B.sort()
    
    # 座標圧縮のためのイベントリストを作成
    events = []
    for _ in range(Q):
        L = int(data[idx]); idx += 1
        R = int(data[idx]); idx += 1
        events.append((L, 1))
        events.append((R+1, -1))
    
    # 座標圧縮対象の点を収集
    points = set(B)
    for e in events:
        points.add(e[0])
    points = sorted(points)
    
    # 座標圧縮マップの作成
    point_to_idx = {p: i for i, p in enumerate(points)}
    
    # imos法による区間加算処理
    count = [0] * (len(points) + 1)
    for pos, delta in events:
        i = point_to_idx[pos]
        count[i] += delta
    
    # 累積和を計算して各ポイントでのフラグ反転回数を求める
    for i in range(1, len(count)):
        count[i] += count[i-1]
    
    # 各会議室について、それが点灯しているかどうかを判定
    ans = 0
    for b in B:
        i = bisect_right(points, b) - 1
        if count[i] % 2 == 1:
            ans += 1
            
    print(ans)

if __name__ == "__main__":
    main()

This editorial was generated by qwen3-coder-480b.

投稿日時:
最終更新: