LOJ#10117. 「一本通 4.1 练习 2」简单题

LOJ#10117. 「一本通 4.1 练习 2」简单题

题目描述

题目来源:$CQOI 2006$

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

例如当$n=20$时,$10$条指令如下:

操作回答操作后的数组
$1 1 10$ N/A $11111111110000000000$
$2 6$ $1$ $11111underline{1}11110000000000$
$2 12$ $0$ $11111111110underline{0}00000000$
$1 5 12$ N/A $11110000001100000000$
$2 6$ $0$ $11110underline{0}00001100000000$
$2 15$ $0$ $11110000001100underline 000000$
$1 6 16$ N/A $11110111110011110000$
$1 11 17$ N/A $11110111111100001000$
$2 12$ $1$ $11110111111underline 100001000$
$2 6$ $1$ $11110underline 111111100001000$

输入格式

第一行包含两个整数$n,m$,表示数组的长度和指令的条数;
以下$m$行,每行的第一个数$t$表示操作的种类:

  • 若$t=1$,则接下来有两个数$L,R$,表示区间$[L,R]$的每个数均反转;
  • 若$t=2$,则接下来只有一个数$i$,表示询问的下标。

输出格式

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

样例

样例输入

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

样例输出

1
0
0
0
1
1

数据范围与提示

对于 $50\%$ 的数据,$1le nle 10^3,1le mle 10^4$
对于 $100\%$ 的数据,$1le nle 10^5,1le mle 5 imes 10^5$,保证 $Lle R$


题解Here!

我怎么一看到这种题就开码线段树呢。。。
感觉自己像个制杖。。。
这个题直接树状数组不就好了?
用树状数组维护异或差分序列,每个元素的真实值是异或前缀和。
修改的时候改$l$和$r+1$两个点即可。
果然比线段树简单多了。。。
附带码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 100010
using namespace std;
int n,m,val[MAXN];
inline int read(){
	int date=0,w=1;char c=0;
	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
	return date*w;
}
inline int lowbit(int x){return x&(-x);}
inline void update(int x){for(;x<=n;x+=lowbit(x))val[x]^=1;}
inline int query(int x){int s=0;for(;x;x-=lowbit(x))s^=val[x];return s;}
void work(){
	int f,x,y;
	n=read();m=read();
	while(m--){
		f=read();x=read();
		if(f==1){
			y=read();
			update(x);update(y+1);
		}
		else printf("%d
",query(x));
	}
}
int main(){
	work();
	return 0;
}
原文地址:https://www.cnblogs.com/Yangrui-Blog/p/10502306.html