P2574 XOR的艺术

P2574 XOR的艺术


区间修改就可以使用线段树来进行维护

而且鉴于xor的特性

0 xor 1 = 1
1 xor 1 =0

所以在处理懒标记的时候就可使1的个数和0的个数互换就可以了

也可以使用做差的方法

因为1/0 xor 1 就相当于减1.

上code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
char base[300000];
struct node
{
	int num_1;
	int num_0;
	int tag;
};
node t[1000000];
void merge(int root)
{
	t[root].num_1=t[root<<1].num_1+t[root<<1|1].num_1;
	t[root].num_0=t[root<<1].num_0+t[root<<1|1].num_0;
	return ;
}
void push_down(int root)
{
	if(t[root].tag)
	{
		t[root].tag=0;
		t[root<<1].tag^=1;
		t[root<<1|1].tag^=1;
		swap(t[root<<1].num_0,t[root<<1].num_1);
		swap(t[root<<1|1].num_0,t[root<<1|1].num_1);
	}
	return ;
}
void build(int root,int l,int r)
{
	if(l==r)
	{
		t[root].num_0=(base[l]=='0' ? 1 : 0);
		t[root].num_1=(base[l]=='1' ? 1 : 0);
		t[root].tag=0;
		return ;
	}
	int mid=(l+r)>>1;
	build(root<<1,l,mid);
	build(root<<1|1,mid+1,r);
	merge(root);
	return ;
}
void change(int root,int nl,int nr,int al,int ar)
{
	if(nl>ar||nr<al)
		return ;
	if(nl>=al&&nr<=ar)
	{
		swap(t[root].num_0,t[root].num_1);
		t[root].tag^=1;
		return ;
	}
	push_down(root);
	int mid=(nl+nr)>>1;
	change(root<<1,nl,mid,al,ar);
	change(root<<1|1,mid+1,nr,al,ar);
	merge(root);
	return ;
}
int check(int root,int nl,int nr,int al,int ar)
{
	if(nl>ar||nr<al)
		return 0;
	if(nl>=al&&nr<=ar)
		return t[root].num_1;
	int mid=(nl+nr)>>1;
	push_down(root);
	int res=check(root<<1,nl,mid,al,ar)+
			check(root<<1|1,mid+1,nr,al,ar);
	merge(root);
	return res;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	scanf("%s",base+1);
	int len=n;
	build(1,1,len);
	int a,b,c;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&a,&b,&c);
		if(!a)
			change(1,1,len,b,c);
		else
			printf("%d\n",check(1,1,len,b,c));
	}
	return 0;
}

打模板的速度还是挺快的。

不跟有些人一样,拿着打模板说事。

posted @ 2018-06-01 20:32  Lance1ot  阅读(141)  评论(0编辑  收藏  举报