# C - Inc, Dec, Xor ## Problem Statement There i...
تم الإنشاء في: ٨ أغسطس ٢٠٢٦
تمت الإجابة باستخدام GPT-5.6 Thinking بواسطة Chat01
تم الإنشاء في: ٨ أغسطس ٢٠٢٦
تمت الإجابة باستخدام GPT-5.6 Thinking بواسطة Chat01
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.
textWhat 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.
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.
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 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.
pythonimport 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 ^=
Let be the number of type-2 queries processed so far.
For each index , while , define
Think of as the time when reaches zero if we keep applying type-2 queries.
Under a type-2 operation, increases by , but does not change for positive elements:
If , then .
The remaining problem is to update the XOR efficiently when every positive value decreases by one.
For any positive integer ,
has bit set exactly when .
Therefore, when every positive is decreased by , bit of the total XOR flips iff
is odd.
But
so
Thus, for every , maintain the parity of the number of active deadlines for each residue modulo .
There are only
such residue slots in total.
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; }
For a positive value ,
where is the largest such that . Hence bit changes during exactly when .
So during query type 2, bit of the XOR changes once for every positive divisible by . Only the parity of their count matters.
Because active elements satisfy
we have
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 to , so
which is exactly what the code performs.
There are residue levels.
This comfortably handles .