分块求调
查看原帖
分块求调
1070629
Yangeper楼主2024/7/25 16:02

P2486

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N = 5e6 + 50;
ll st[N], ed[N], pos[N];
bool add[N];
ll a[N], sum[N];
ll n, m;
ll block, t;
void update(ll L, ll R){
	ll p = pos[L], q = pos[R];
	if(p == q){
		for(ll i = L; i <=R; i++){
			ll o0 = a[i] ? -1 : 1;
			a[i] += o0, sum[p] += o0;
		}
	}
	else{
		if(L != st[p]){
			for(ll i = L; i <= ed[p]; i++){
				ll o0 = a[i] ? -1 : 1;
				a[i] += o0, sum[p] += o0;
			}
		}
		else add[p] = !add[p], sum[p] = block - sum[p];
		if(R != ed[q]){
			for(ll i = st[q]; i <= R; i++){
				ll o0 = a[i] ? -1 : 1;
				a[i] += o0, sum[q] += o0;
			}
		}
		else add[q] = !add[q], sum[q] = block - sum[q];
		for(ll i = p + 1; i <= q - 1; i++)
			add[i] = !add[i], sum[i] = block - sum[i];
	}
}

ll quere(ll L, ll R){
	ll p = pos[L], q = pos[R];
	ll ans = 0;
	if(p == q){
		for(ll i = L; i <= R; i++) ans += a[i];
		if(add) ans = (R - L + 1) - ans;
	}
	else{
		if(L != st[p]) {
			for(ll i = L; i <= ed[p]; i++) ans += a[i];
			if(add[p]) ans = (ed[p] - L + 1) - ans;
		}
		else ans += sum[p];
		if(R != ed[q]) {
			for(ll i = st[q]; i <= R; i++) ans += a[i];
			if(add[q]) ans = (R - st[q] + 1) - ans;
		}
		else ans += sum[q];
		for(ll i = p + 1; i <= q - 1; i++) ans += sum[i];
	}
	return ans;
}


int main(){
	scanf("%lld%lld", &n, &m);
	block = sqrt(n), t = n / block;
	if(n % block) t++;
	for(ll i = 1; i <= t; i++)
		st[i] = (i - 1) * block + 1, ed[i] = i * block;
	ed[t] = n;
	for(ll i = 1; i <= n; i++)
		pos[i] = (i - 1) / block + 1;
	
	while(m--){
		ll x, y, z;
		scanf("%lld%lld%lld", &z, &x, &y);
		if(z) printf("%lld\n", quere(x, y));
		else update(x, y);
	}
} 
2024/7/25 16:02
加载中...