当前位置: 代码迷 >> 综合 >> CQOI2006[简单题](树状数组 + 异或)
  详细解决方案

CQOI2006[简单题](树状数组 + 异或)

热度:79   发布时间:2023-11-21 11:57:30.0

Description

  有一个n个元素的数组,每个元素初始均为0。有m条指令,要么让其中一段连续序列数字反转——0变1,1变0(操作1),要么询问某个元素的值(操作2)。例如当n=20时,10条指令如下:
    

Input

  第一行包含两个整数n,m,表示数组的长度和指令的条数,以下m行,每行的第一个数t表示操作的种类。若t=1,则接下来有两个数L, R (L<=R),表示区间[L, R]的每个数均反转;若t=2,则接下来只有一个数I,表示询问的下标。

Output

  每个操作2输出一行(非0即1),表示每次操作2的回答

Sample Input

20 10 1 1 10 2 6 2 12 1 5 12 2 6 2 15 1 6 16 1 11 17 2 12 2 6

Sample Output

1 0 0 0 1 1

Hint

  50%的数据满足:1<=n<=1,000,1<=m<=10,000
  100%的数据满足:1<=n<=100,000,1<=m<=500,000

 

对于一个01序列来说,将其全部取反等价于整个序列异或1

区间修改单点查询,BIT维护异或差分即可

#include <bits/stdc++.h>
#define Lowbit(x) x & -x 
using namespace std;const int MAXN = 100100;
const int INF = 0x3f3f3f3f;template <typename T> inline void read(T &x) {int ch = getchar();bool fg = false;for (x = 0; !isdigit(ch); ch = getchar()) {if (ch == '-') {fg = true;}}for (; isdigit(ch); ch = getchar()) {x = x * 10 + ch - '0';}if (fg) {x = -x;}
}int n, Q;int tre[MAXN];void update(int x, int y) {for(int i = x; i <= MAXN; i += Lowbit(i)) tre[i] ^= y;
}int query(int x) {int ret = 0;for(int i = x; i; i -= Lowbit(i)) ret ^= tre[i];return ret;
}signed main() {read(n); read(Q);while(Q--) {int com, l, r;read(com);if(com == 1) {read(l), read(r);update(l, 1);update(r + 1, 1);}else {read(l);printf("%d\n", query(l));}}return 0;
}