Official

C - カードの重ね置き / Stacking Cards Editorial by admin

GPT 5.2 High

Overview

This problem asks you to process PUT / REMOVE / LOOK operations on a stack of cards in order, and for each LOOK, determine when (at which previous LOOK number) the “XOR of the entire stack” was last seen.

Analysis

Key Insight 1: The XOR of the entire stack can be maintained with “incremental updates”

If you recompute the XOR of all cards in the stack from scratch each time, each LOOK could take up to the number of cards in the stack. In the worst case, inputs like: - Performing PUT \(10^5\) times to grow the stack large, - Then performing LOOK \(10^5\) times

are possible, and naively recomputing the XOR each time results in a total of \(O(N^2)\), causing TLE.

Here we use properties of XOR:

  • XOR is commutative and associative, so order doesn’t matter
  • \(a \oplus a = 0\)
  • \(x \oplus a \oplus a = x\) (XORing the same value twice restores the original)

Therefore, by maintaining the XOR of the entire stack as xor_all: - PUT c: xor_all ^= c - REMOVE (let \(x\) be the removed value): xor_all ^= x

we can always update the current XOR of the entire stack in \(O(1)\).

Key Insight 2: Use a dictionary to track “the LOOK number where the same XOR last appeared”

What we want for each LOOK with value \(v_i\) is “the most recent LOOK number where the same value appeared,” so we can manage: - last[v] = the LOOK number where XOR value v was last seen

using a dictionary (associative array).

For example, if the LOOK results in order are 5, 7, 5, then: - 1st time (5): not seen before, so -1; set last[5]=1 - 2nd time (7): not seen before, so -1; set last[7]=2 - 3rd time (5): last[5]=1 exists, so output 1; update last[5]=3

Algorithm

  1. Prepare a stack stack to manage the cards in the pile (needed to know the value removed by REMOVE).
  2. Maintain a variable xor_all holding “the current XOR of the entire stack” (initial value 0).
  3. Maintain a dictionary last mapping “XOR value → the LOOK number where that value was last seen.”
  4. Count LOOK occurrences with a counter look_idx starting from 1.
  5. Process each operation in order:
    • PUT c:
      • stack.append(c)
      • xor_all ^= c
    • REMOVE:
      • x = stack.pop()
      • xor_all ^= x
    • LOOK:
      • look_idx += 1
      • v = xor_all
      • The answer is the number stored in last if it exists, otherwise -1
      • Then update last[v] = look_idx

This allows every operation to be processed in \(O(1)\).

Complexity

  • Time complexity: \(O(N)\) (each operation takes constant time)
  • Space complexity: \(O(N)\) (the stack and dictionary hold at most \(N\) elements)

Implementation Notes

  • For REMOVE, you need “the value of the removed card” to update xor_all, so cards must always be pushed onto the stack.

  • The LOOK numbering counts “how many times LOOK has occurred,” so look_idx is tracked separately from the overall operation index.

  • Using last.get(v, -1) provides a concise way to write “return -1 if not found.”

    Source Code

import sys

def main():
    input = sys.stdin.buffer.readline
    N = int(input())
    stack = []
    xor_all = 0
    last = {}  # xor value -> last LOOK index
    ans = []
    look_idx = 0

    for _ in range(N):
        parts = input().split()
        if parts[0] == b'PUT':
            c = int(parts[1])
            stack.append(c)
            xor_all ^= c
        elif parts[0] == b'REMOVE':
            x = stack.pop()
            xor_all ^= x
        else:  # LOOK
            look_idx += 1
            v = xor_all
            ans.append(str(last.get(v, -1)))
            last[v] = look_idx

    sys.stdout.write("\n".join(ans))

if __name__ == "__main__":
    main()

This editorial was generated by gpt-5.2-high.