线段树10pts
查看原帖
线段树10pts
332486
233小问号楼主2021/7/13 11:50

rt 本来在做TJOI开关 想着双倍经验 结果爆炸

#include<bits/stdc++.h>
#define lc(x) (x<<1)
#define	rc(x) (x<<1|1)
using namespace std;
const int mxn=1e6+1;
int light[mxn<<2];
bool lazy_tag[mxn<<2];
inline void init(int root,int start,int end)
{
	if(start==end)
	{
		char a;
		cin>>a;
		light[root]=a-48;
		return;
	}
	int mid=(start+end)>>1;
	init(lc(root),start,mid);
	init(rc(root),mid+1,end);
	light[root]=light[lc(root)]+light[rc(root)];
}
inline void pushdown(int root,int left_range,int right_range)
{
	int len=right_range-left_range+1;
	if(lazy_tag[root])
	{
		lazy_tag[lc(root)]^=1;
		lazy_tag[rc(root)]^=1;
		int mid=(left_range+right_range)>>1;
		light[lc(root)]=(len-(len>>1))-light[lc(root)];
		light[rc(root)]=(len>>1)-light[rc(root)];
		lazy_tag[root]=0;
	}
	return;
}
inline void modify(int root,int left_range,int right_range,int start,int end)
{
	if(start<=left_range && right_range<=end)
	{
		light[root]=(right_range-left_range+1)-light[root];
		lazy_tag[root]^=1;
		return;
	}
	pushdown(root,start,end);
	int mid=(left_range+right_range)>>1;
	if(start<=mid)	modify(lc(root),left_range,mid,start,end);	
	if(mid<end)	modify(rc(root),mid+1,right_range,start,end);
	light[root]=light[lc(root)]+light[rc(root)];
}
inline long long query(int root,int left_range,int right_range,int start,int end)
{
	if(start<=left_range && right_range<=end)
		return light[root];
	pushdown(root,left_range,right_range);
	long long a=0,b=0,mid=(left_range+right_range)>>1;
	if(start<=mid) a=query(lc(root),left_range,mid,start,end);
    if(mid<end) b=query(rc(root),mid+1,right_range,start,end);
    return a+b;
}
int main(){
	ios::sync_with_stdio(0);
	long long n,m,left_range,right_range;
	cin>>n>>m;
	init(1,1,n);
	for(long long i=1;i<=m;i++)
	{
		bool op;
		cin>>op>>left_range>>right_range;
		if(op==0)
			modify(1,1,n,left_range,right_range);
		else
			cout<<query(1,1,n,left_range,right_range)<<endl;
	} 
	return 0;
}
2021/7/13 11:50
加载中...