题目大意
Inc, Dec, Xor
有一个长度为 N 的整数序列 A=(A1,A2,…,AN),初始时 A 的所有元素均为 0。
给定 Q 个操作,请按顺序依次处理。操作共有两种,格式如下:
-
1 x:将 Ax 的值增加 1。
-
2:对每个 i=1,2,…,N,若 Ai≥1,则将 Ai 的值减少 1。
请求出每次操作处理完毕后 A1,A2,…,AN 的按位异或值。
关于按位异或
非负整数 A,B 的按位异或 A⊕B 定义如下:A⊕B 在二进制表示下 2k(k≥0)位上的数字,当 A,B 在二进制表示下 2k 位上的数字恰有一个为 1 时为 1,否则为 0。
例如 3⊕5=6(二进制表示为 011⊕101=110)。
一般地,k 个非负整数 p1,p2,…,pk 的按位异或定义为 (…((p1⊕p2)⊕p3)⊕⋯⊕pk),可以证明其结果与 p1,p2,…,pk 的顺序无关。
输入从标准输入按以下格式给出:
1 2 3 4 5
| N Q query_1 query_2 ⋮ query_Q
|
其中每个操作为以下两种格式之一:
输出 Q 行。
第 i 行(1≤i≤Q)输出第 i 个操作处理完毕后 A1,A2,…,AN 的按位异或值。
处理第 1 个操作后 A=(0,1),0,1 的按位异或为 1,故第 1 行输出 1。
处理第 2 个操作后 A=(0,2),0,2 的按位异或为 2,故第 2 行输出 2。
处理第 3 个操作后 A=(1,2),1,2 的按位异或为 3,故第 3 行输出 3。
处理第 4 个操作后 A=(0,1),0,1 的按位异或为 1,故第 4 行输出 1。
处理第 5 个操作后 A=(0,0),0,0 的按位异或为 0,故第 5 行输出 0。
1 2 3 4 5 6 7 8 9
| 3 8 1 2 1 3 1 1 1 2 1 1 2 1 3 1 1
|
思路讲解
那么这道题目的关键点就是这个,初始时 A 的所有元素均为 0,以及我们只能增加一个元素啊,我们只要实时维护一个这个正数的这个集合,遇到操作二暴力遍历就可以解决了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| int main() { int n = readInt(), q = readInt();
vector<int> alive; alive.reserve(min(n, q));
int cur = 0;
while (q--) { int op = readInt();
if (op == 1) { int x = readInt();
if (A[x] == 0) alive.push_back(x);
cur ^= A[x]; ++A[x]; cur ^= A[x]; } else {
int m = 0; for (int idx : alive) { cur ^= A[idx]; --A[idx]; cur ^= A[idx];
if (A[idx] > 0) alive[m++] = idx; } alive.resize(m); }
IO::writeInt(cur); }
IO::flushOut(); return 0; }
|
AC代码
https://atcoder.jp/contests/abc470/submissions/78274919
AI 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include <bits/stdc++.h> using namespace std;
namespace IO { const int BUF = 1 << 16; char ibuf[BUF], *ip1 = ibuf, *ip2 = ibuf;
inline char gc() { if (ip1 == ip2) { ip2 = (ip1 = ibuf) + fread(ibuf, 1, BUF, stdin); if (ip1 == ip2) return EOF; } return *ip1++; } inline int readInt() { int c = gc(), x = 0; while (c < '0' || c > '9') c = gc(); while (c >= '0' && c <= '9') { x = x * 10 + (c - '0'); c = gc(); } return x; }
char obuf[BUF], *op = obuf; inline void flushOut() { fwrite(obuf, 1, op - obuf, stdout); op = obuf; } inline void pc(char c) { if (op == obuf + BUF) flushOut(); *op++ = c; } inline void writeInt(int x) { char tmp[12]; int len = 0; do { tmp[len++] = char('0' + x % 10); x /= 10; } while (x); while (len) pc(tmp[--len]); pc('\n'); } } using IO::readInt;
int A[500005];
int main() { int n = readInt(), q = readInt();
vector<int> alive; alive.reserve(min(n, q));
int cur = 0;
while (q--) { int op = readInt();
if (op == 1) { int x = readInt();
if (A[x] == 0) alive.push_back(x);
cur ^= A[x]; ++A[x]; cur ^= A[x]; } else {
int m = 0; for (int idx : alive) { cur ^= A[idx]; --A[idx]; cur ^= A[idx];
if (A[idx] > 0) alive[m++] = idx; } alive.resize(m); }
IO::writeInt(cur); }
IO::flushOut(); return 0; }
|
心路历程(WA,TLE,MLE……)