# C - Inc, Dec, Xor ## Problem Statement There i...

Criado em: 8 de agosto de 2026

Respondido usando GPT-5.6 Thinking por Chat01

Pergunta

C - Inc, Dec, Xor

Problem Statement

There is a length-NNN integer sequence A=(A1,A2,…,AN)A=(A_1,A_2,\ldots,A_N)A=(A1​,A2​,…,AN​). Initially, all elements of AAA are 000.
You will be given QQQ queries, which should be processed in order. There are two types of queries, each given in one of the following formats:

1 x: Increase the value of AxA_xAx​ by 111.
2: For each i=1,2,…,Ni=1,2,\ldots,Ni=1,2,…,N, if Ai≥1A_i \geq 1Ai​≥1, decrease the value of AiA_iAi​ by 111.

Find the bitwise XOR\mathrm{XOR}XOR of A1,A2,…,ANA_1,A_2,\ldots,A_NA1​,A2​,…,AN​ immediately after processing each query.

text
What is bitwise XOR\mathrm{XOR}XOR? The bitwise XOR\mathrm{XOR}XOR of non-negative integers AAA and BBB, denoted A⊕BA \oplus BA⊕B, is defined as follows: In the binary representation of A⊕BA \oplus BA⊕B, the digit in the 2k2^k2k (k≥0k \geq 0k≥0) place is 111 if exactly one of the digits in the 2k2^k2k place of AAA and BBB in their binary representations is 111, and 000 otherwise. For example, 3⊕5=63 \oplus 5 = 63⊕5=6 (in binary: 011⊕101=110011 \oplus 101 = 110011⊕101=110). More generally, the bitwise XOR\mathrm{XOR}XOR of kkk non-negative integers p1,p2,p3,…,pkp_1, p_2, p_3, \dots, p_kp1​,p2​,p3​,…,pk​ is defined as (…((p1⊕p2)⊕p3)⊕⋯⊕pk)(\dots ((p_1 \oplus p_2) \oplus p_3) \oplus \dots \oplus p_k)(…((p1​⊕p2​)⊕p3​)⊕⋯⊕pk​), and it can be proved that this value does not depend on the order of p1,p2,p3,…,pkp_1, p_2, p_3, \dots, p_kp1​,p2​,p3​,…,pk​.

Constraints

1≤N≤5×1051\le N\le 5\times 10^51≤N≤5×105
1≤Q≤5×1051\le Q\le 5\times 10^51≤Q≤5×105
1≤x≤N1\le x\le N1≤x≤N
All input values are integers.

Input

The input is given from Standard Input in the following format:
NNN QQQ
query1\text{query}_1query1​
query2\text{query}_2query2​
⋮\vdots⋮
queryQ\text{query}_QqueryQ​

Each query is given in one of the following 222 formats:
111 xxx

222

Output

Output QQQ lines.
The iii-th line (1≤i≤Q)(1\le i\le Q)(1≤i≤Q) should contain the bitwise XOR\mathrm{XOR}XOR of A1,A2,…,ANA_1,A_2,\ldots,A_NA1​,A2​,…,AN​ for AAA immediately after processing the iii-th query.

Python

python
import random, math def solve_fast(N, queries): Q=len(queries) K=(Q.bit_length()) # k=0..K-1 enough for bits up to Q par=[bytearray(1<<k) for k in range(K)] bucket=[0]*(Q+2) d=[0]*N t=0 xr=0 out=[] def toggle_deadline(v): for k in range(K): par[k][v & ((1<<k)-1)] ^= 1 for q in queries: if q[0]==1: x=q[1] old=d[x] if old>t: a=old-t xr ^= a ^ (a+1) bucket[old]-=1 toggle_deadline(old) old+=1 d[x]=old bucket[old]+=1 toggle_deadline(old) else: xr ^=

Pensamento

Formulated residue-array memory and validated algorithm

Worked for 1m 2s

Resposta

Idea

Let tt be the number of type-2 queries processed so far.

For each index ii, while Ai>0A_i>0, define

Di=t+Ai.D_i=t+A_i.

Think of DiD_i as the time when AiA_i reaches zero if we keep applying type-2 queries.

Under a type-2 operation, tt increases by 11, but DiD_i does not change for positive elements:

Ai=Dit.A_i=D_i-t.

If DitD_i\le t, then Ai=0A_i=0.

The remaining problem is to update the XOR efficiently when every positive value decreases by one.


For any positive integer xx,

x(x1)x\oplus(x-1)

has bit kk set exactly when 2kx2^k\mid x.

Therefore, when every positive AiA_i is decreased by 11, bit kk of the total XOR flips iff

#{i:Ai>0, 2kAi}\#\{i:A_i>0,\ 2^k\mid A_i\}

is odd.

But

Ai=Dit,A_i=D_i-t,

so

2kAi    Dit(mod2k).2^k\mid A_i \iff D_i\equiv t\pmod {2^k}.

Thus, for every kk, maintain the parity of the number of active deadlines DiD_i for each residue modulo 2k2^k.

There are only

1+2+4++2log2Q=O(Q)1+2+4+\cdots+2^{\lfloor\log_2 Q\rfloor}=O(Q)

such residue slots in total.

C++17

cpp
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, Q; cin >> N >> Q; // Bits that can occur in values <= Q. int K = 0; while ((1 << K) <= Q) ++K; // parity[k][r]: // parity of the number of active deadlines D // satisfying D % 2^k == r. vector<vector<unsigned char>> parity(K); for (int k = 0; k < K; ++k) { parity[k].assign(1 << k, 0); } // deadline[i] is meaningful as an active deadline iff deadline[i] > t. vector<int> deadline(N, 0); // Number of active elements having exactly this deadline. vector<int> cnt(Q + 2, 0); int t = 0; int xr = 0; // Toggle the contribution of one deadline in all parity tables. auto toggle = [&](int d) { for (int k = 0; k < K; ++k) { int mask = (1 << k) - 1; parity[k][d & mask] ^= 1; } }; while (Q--) { int type; cin >> type; if (type == 1) { int x; cin >> x; --x; int d = deadline[x]; if (d > t) { // Currently A[x] = d - t > 0. int a = d - t; // Replace a by a+1 in the total XOR. xr ^= a; xr ^= (a + 1); // Move its deadline d -> d+1. --cnt[d]; toggle(d); ++d; deadline[x] = d; ++cnt[d]; toggle(d); } else { // Currently A[x] = 0. // It becomes 1, hence deadline t+1. xr ^= 1; int nd = t + 1; deadline[x] = nd; ++cnt[nd]; toggle(nd); } } else { // Before increasing t, every active A_i is positive. // // Bit k flips iff the number of active D_i satisfying // D_i == t (mod 2^k) is odd. for (int k = 0; k < K; ++k) { int mask = (1 << k) - 1; int residue = t & mask; if (parity[k][residue]) { xr ^= (1 << k); } } ++t; // Deadlines equal to the new t have just reached A_i = 0. // Remove all of them from the active parity structures. // // Since the structures store parity, removing cnt[t] // identical entries matters only when cnt[t] is odd. if (cnt[t] & 1) { toggle(t); } cnt[t] = 0; } cout << xr << '\n'; } return 0; }

Why it is correct

For a positive value xx,

x(x1)=2v2(x)+11,x\oplus(x-1)=2^{v_2(x)+1}-1,

where v2(x)v_2(x) is the largest ee such that 2ex2^e\mid x. Hence bit kk changes during xx1x\to x-1 exactly when 2kx2^k\mid x.

So during query type 2, bit kk of the XOR changes once for every positive AiA_i divisible by 2k2^k. Only the parity of their count matters.

Because active elements satisfy

Ai=Dit,A_i=D_i-t,

we have

2kAi    Dimod2k=tmod2k.2^k\mid A_i \iff D_i\bmod 2^k=t\bmod2^k.

parity[k][t mod 2^k] stores precisely the parity we need, so the type-2 update of xr is correct.

For a type-1 query, only one value changes from aa to a+1a+1, so

XORnew=XORolda(a+1),\text{XOR}_{new} = \text{XOR}_{old}\oplus a\oplus(a+1),

which is exactly what the code performs.

Complexity

There are O(logQ)O(\log Q) residue levels.

  • Type 1: O(logQ)O(\log Q)
  • Type 2: O(logQ)O(\log Q)
  • Total: O(QlogQ+N)O(Q\log Q+N)
  • Memory: O(N+Q)O(N+Q)

This comfortably handles N,Q5×105N,Q\le5\times10^5.

Compartilhar esta Q&A