十分分块求调(悬关)
查看原帖
十分分块求调(悬关)
522067
_Violet_Evergarden楼主2023/8/23 19:06
#include<bits/stdc++.h>
using namespace std;
long long n,m;
long long L[10000001];
long long R[10000001];
long long pos[10000001];
long long sum[10000001];
long long add[10000001];
long long w[10000001];
long long t; 
long long op;
long long l,r;
long long ans;
void change(long long l,long long r){
	int p=pos[l],q=pos[r];
	if(p==q){
		for(int i=l;i<=r;i++){
			if(w[i]){
				w[i]=0;
				sum[p]--;
			}
			else{
				w[i]=1;
				sum[p]++;
			}
		}
		return;
	}
	for(int i=l;i<=R[p];i++){
		if(w[i]){
				w[i]=0;
				sum[p]--;
			}
			else{
				w[i]=1;
				sum[p]++;
			}
	}
	for(int i=L[q];i<=r;i++){
		if(w[i]){
			w[i]=0;
			sum[q]--;
		}
		else{
			w[i]=1;
			sum[q]++;
		}
	}
	for(int i=p+1;i<=q-1;i++){
		add[i]++;
		add[i]%=2;
		sum[i]=(R[i]-L[i]+1)-sum[i];
	}
}
long long query(long long l,long long r){
	int p=pos[l],q=pos[r];
	ans=0;
	if(add[q]){
		for(int i=L[q];i<=R[q];i++){
			if(w[i]){
				w[i]=0;	
			}
			else{
				w[i]=1;
			}
		}
		add[q]=0;
	}
	if(add[p]){
		for(int i=L[p];i<=R[p];i++){
			if(w[i]){
				w[i]=0;	
			}
			else{
				w[i]=1;
			}
		}
		add[q]=0;
	}
	if(p==q){
		for(int i=l;i<=r;i++){
			if(w[i]){
				ans++;
			}
		}
	}
	for(int i=l;i<=R[p];i++){
		if(w[i]){
			ans++;
		}
	}
//	cout<<ans<<" "<<R[p]<<endl;
	for(int i=L[q];i<=r;i++){
		if(w[i]){
			ans++;
		}
	}
//	cout<<ans<<" "<<L[q]<<endl;
	for(int i=p+1;i<=q-1;i++){
		ans+=sum[i];
	}
//	cout<<ans<<endl;
	return ans;
}
int main(){
	cin>>n>>m;
	l=sqrt(n);
	t=l;
	for(int i=1;i<=t;i++)
	{
		L[i]=R[i-1]+1;
		R[i]=i*l;
//		cout<<L[i]<<"!"<<R[i]<<endl;
	}
	if(R[t]<n)
	{
		t++;
		L[t]=R[t-1]+1;
		R[t]=n;
	}
	for(int i=1;i<=t;i++)
	{
		for(int j=L[i];j<=R[i];j++)
		{
			pos[j]=i;
		}
	}
	for(int i=1;i<=m;i++){
		cin>>op;
		if(op==0){
			cin>>l>>r;
			change(l,r);
		}
		else{
			cin>>l>>r;
			cout<<query(l,r)<<endl;
		}
	}
	return 0;
}
2023/8/23 19:06
加载中...