【树状数组】【CQOI2006】简单题

【题目描述】

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


【输入格式】

    第一行包含两个整数n,m,表示数组的长度和指令的条数,以下m行,每行的第一个数t表示操作的种类。若t=1,则接下来有两个数L, R (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%的数据满足:1<=n<=1,000,1<=m<=10,000

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

水题,无需线段树,树状数组即可。

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
int tree[400005],n,m;
int lowbit(int k)
{
	return k&-k;
}
int sum(int x)
{
	int ans=0;
	while(x>0)
	{
		ans+=tree[x];
		x-=lowbit(x);
	}
	return ans;
}
void add(int x,int k)
{
	while(x<=n)
	{
		tree[x]+=k;
		x+=lowbit(x);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int t;
		scanf("%d",&t);
		if(t==1)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			add(x,1);
			add(y+1,-1);
		}
		else
		{
			int x;
			scanf("%d",&x);
			printf("%d\n",sum(x)%2);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/dy_dream/article/details/80185452