C - カードの重ね置き / Stacking Cards Editorial by admin
GPT 5.2 HighOverview
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
- Prepare a stack
stackto manage the cards in the pile (needed to know the value removed byREMOVE). - Maintain a variable
xor_allholding “the current XOR of the entire stack” (initial value 0). - Maintain a dictionary
lastmapping “XOR value → the LOOK number where that value was last seen.” - Count
LOOKoccurrences with a counterlook_idxstarting from 1. - Process each operation in order:
PUT c:stack.append(c)xor_all ^= c
REMOVE:x = stack.pop()xor_all ^= x
LOOK:look_idx += 1v = xor_all- The answer is the number stored in
lastif 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 updatexor_all, so cards must always be pushed onto the stack.The
LOOKnumbering counts “how many timesLOOKhas occurred,” solook_idxis 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.