10分求调
查看原帖
10分求调
761183
sheryang_UKE楼主2023/7/17 13:56

代码如下(本人蒟蒻)

#include <bits/stdc++.h>
using namespace std;
const int maxn=100005;
struct tree{
	int l,r;
	int l0,l1,add; // l0:关着的灯的数量 l1:表示 亮着的灯的数量 
} t[maxn*4];
void build(int u,int l,int r)  //建树
{ 
	t[u].l=l;    
	t[u].r=r;
	if (l==r) 
	{
		t[u].l0++;
		return ;
	}
	int mid=(l+r)/2;
	build(u*2,l,mid); 
	build(u<<1|1,mid+1,r);
	t[u].l0=t[u*2].l0 + t[u<<1|1].l0;  
}
inline void spread(int u) //打标记 
{
	if (t[u].add == 0) return ;
	swap(t[u*2].l0,t[u*2].l1);  //交换
	swap(t[u<<1|1].l0, t[u<<1|1].l1);
	t[u*2].add^=1;  //开关灯就相当于^一下 
	t[u<<1|1].add^=1;
	t[u].add=0;
}
int ask(int u,int l,int r) //查询开着的灯的数量 
{ 	
	if (t[u].l>=l&&t[u].r<=r) 
		return t[u].l1;
	spread(u);
	int mid=(t[u].l+t[u].r)/2,sum = 0;
	if(l<=mid) sum+=ask(u*2,l,r);
	if(mid<r)  sum+=ask(u<<1|1,l,r);
	return sum;
}
void change(int u,int l,int r)//开关灯 
{	
	if (t[u].l>=l&&t[u].r<=r) 
	{
		t[u].add=1;
		swap(t[u].l0,t[u].l1);
		return ;
	}
	spread(u);
	int mid = (t[u].l + t[u].r) / 2;
	if (l <= mid) change(u*2, l, r);
	if (mid < r) change(u<<1|1, l, r);
	t[u].l0 = t[u*2].l0 + t[u<<1|1].l0;
	t[u].l1 = t[u*2].l1 + t[u<<1|1].l1;
}
int main()
{
	int n,m,opt,x,y;
	cin>>n>>m;
	build(1, 1, n);
	for (int i=1;i<=m;i++) 
	{
		cin>>opt>>x>>y;
		if (opt == 0) 
			change(1, x, y);
		else 
			cout<<ask(1, x, y)<<endl;
	}
	return 0;
}
2023/7/17 13:56
加载中...