公式

B - 電光掲示板の更新 / Updating the Electronic Message Board 解説 by admin

Claude 4.6 Opus (Thinking)

Overview

This is a problem where, each time a character on an electronic bulletin board is changed one at a time, we need to efficiently compute the number of “matching pairs” — adjacent cells that share the same character.

Analysis

Naive Approach and Its Issues

If we scan all cells and recount matching pairs after every update, each update costs \(O(N)\), resulting in \(O(NQ)\) overall. Since \(N\) can be up to \(10^6\) and \(Q\) up to \(10^5\), this leads to up to \(10^{11}\) operations in the worst case, causing TLE.

Key Insight: Focus on Local Changes

When a single character is changed, the only thing that affects the number of matching pairs is the relationship between the changed cell and its left and right neighbors.

Specifically, when changing the character at position \(i\), at most two pairs are affected: - The pair \((i-1, i)\) (if \(i > 1\)) - The pair \((i, i+1)\) (if \(i < N\))

For example, if the string is AABA and we change position 3 (0-indexed: 2) to A: - Before change: pair \((2,3)\) is B and A (mismatch), pair \((3,4)\) is A and A (match) - After change: pair \((2,3)\) is A and A (match, +1), pair \((3,4)\) is A and A (match, no change)

In this way, we simply subtract matches with the old character and add matches with the new character, allowing us to update the count in \(O(1)\).

Algorithm

  1. Initialization: Store the string \(S\) as an array and count the number of adjacent matching pairs count in \(O(N)\).
  2. Each update operation (change position \(i\) to character \(c\)):
    • Only process if the current character old = S[i] differs from the new character \(c\).
    • Update relationship with left neighbor \((i-1)\):
      • If S[i-1] == old, then count -= 1 (a previously matching pair may break)
      • If S[i-1] == c, then count += 1 (a new matching pair may form)
    • Update relationship with right neighbor \((i+1)\):
      • If S[i+1] == old, then count -= 1
      • If S[i+1] == c, then count += 1
    • Update the array with S[i] = c.
  3. Output count after each update.

Complexity

  • Time complexity: \(O(N + Q)\) (\(O(N)\) for the initial count, \(O(1)\) per update)
  • Space complexity: \(O(N)\) (storing the string as an array)

Implementation Notes

  • 0-indexed and 1-indexed conversion: Since the problem uses 1-indexed positions, subtract 1 from the input to convert to 0-indexed.

  • Skipping when there is no change: If old == c, the number of matching pairs does not change, so we skip processing with a conditional branch to avoid unnecessary computation.

  • Output optimization: In Python, calling print each time is slow, so accumulate results in a list and output all at once with sys.stdout.write at the end. Similarly, use sys.stdin.readline for input.

  • Boundary checks: At the left end (\(i = 0\)) or right end (\(i = N-1\)), there is only one adjacent cell, so conditional branches are needed to prevent out-of-bounds access.

    Source Code

import sys
input = sys.stdin.readline

def main():
    N, Q = map(int, input().split())
    S = list(input().strip())
    
    # Count initial matching pairs
    count = 0
    for i in range(N - 1):
        if S[i] == S[i + 1]:
            count += 1
    
    out = []
    for _ in range(Q):
        line = input().split()
        idx = int(line[0]) - 1  # 0-indexed
        c = line[1]
        
        old = S[idx]
        if old != c:
            # Check left neighbor
            if idx > 0:
                if S[idx - 1] == old:
                    count -= 1
                if S[idx - 1] == c:
                    count += 1
            # Check right neighbor
            if idx < N - 1:
                if S[idx + 1] == old:
                    count -= 1
                if S[idx + 1] == c:
                    count += 1
            S[idx] = c
        
        out.append(str(count))
    
    sys.stdout.write('\n'.join(out) + '\n')

main()

This editorial was generated by claude4.6opus-thinking.

投稿日時:
最終更新: