10pts求助
查看原帖
10pts求助
800322
Zouzhuoxuan楼主2023/2/1 10:54
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int n,m,len,ku[100005],ans[100005];
bool a[100005]/*灯的状态*/,tap[100005]/*块的状态*/;
int search(int x,int y)
{
	int num=0,i;
	for(i=x;i<=min(y,ku[x]*len);i++) num+=(a[i]^tap[ku[x]]); //x->dx
	if(ku[x]!=ku[y]) for(i=(ku[y]-1)*len+1;i<=y;i++) num+=(a[i]^tap[ku[y]]); //dy->y
	for(i=ku[x]+1;i<=ku[y]-1;i++) num+=ans[i]; //dx->dy,整块加维护的ans 
	return num;
}
void change(int x,int y)
{
	int i;
	for(i=x;i<=min(y,ku[x]*len);i++)  //处理x->dx(ku[x]这块) 
	{
		ans[ku[x]]-=(a[i]^tap[ku[x]]); //0^1=1^0=1,0^0=1^1=0
		a[i]^=1;
		ans[ku[x]]+=(a[i]^tap[ku[x]]); //维护ans 
	}
	if(ku[x]!=ku[y]) //若x和y不在一块,则处理dy->y(ku[y]这块) 
	{
		for(i=(ku[y]-1)*len+1;i<=y;i++)
		{
			ans[ku[y]]-=(a[i]^tap[ku[y]]); //只因本同上
			a[i]^=1;
			ans[ku[x]]+=(a[i]^tap[ku[y]]);
		}
	}
	for(i=ku[x]+1;i<=ku[y]-1;i++) //处理dx->dy(即ku[x]的右区间和ku[y]的左区间之间的块,整块处理)
	{
		tap[i]^=1;
		ans[i]=len-ans[i];
	} 
}
int main()
{
	memset(a,false,sizeof(a));
	memset(tap,false,sizeof(tap));
	memset(ku,0,sizeof(ku));
	memset(ans,0,sizeof(ans));
	int i,t,x,y;
	scanf("%d%d",&n,&m);
	len=sqrt(n);
	for(i=1;i<=n;i++) ku[i]=(i-1)/len+1;
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d",&t,&x,&y);
		if(!t) change(x,y);
		else printf("%d\n",search(x,y));
	}
}
2023/2/1 10:54
加载中...