分块练习模板

class Block{
public:
	typedef long long int ll;
	Block(int _n){
		n = _n;
		//源值
		value.assign(n + 1, 0);
		//块和
		sum.assign(n + 1, 0);
		//附加值
		add.assign(n + 1, 0);
		//确定块大小
		blen = pow(n, 0.33);
		//分配块编号
		idx.assign(n + 1, 0);
		for (int i = 1; i <= n; i++){
			idx[i] = (i - 1) / blen + 1;
		}
	}
	ll fun(ll a, ll b){
		return a ^ b;
	}
	void modfiy(int l, int r, ll v){
		int len = min(idx[l] * blen, r);
		//左边多出的
		for (int i = l; i <= len; i++){
			sum[idx[i]] -= fun(value[i], add[idx[i]]);
			value[i] = fun(value[i],v);
			sum[idx[i]] += fun(value[i], add[idx[i]]);
		}
		//右边多出的
		if (idx[l] != idx[r]){
			for (int i = (idx[r] - 1) * blen + 1; i <= r; i++){
				sum[idx[i]] -= fun(value[i], add[idx[i]]);
				value[i] = fun(value[i], v);
				sum[idx[i]] += fun(value[i], add[idx[i]]);
			}
		}
		//连续块
		for (int i = idx[l] + 1; i < idx[r]; i++){
			add[i] = fun(add[i],1);
			sum[i] = blen - sum[i];
		}
	}
	ll query(int l, int r){
		ll len = min(idx[l] * blen, r), ans = 0;
		//左边多出的
		for (int i = l; i <= len; i++){
			ans += fun(value[i], add[idx[i]]);
		}
		//右边多出的
		if (idx[l] != idx[r]){
			for (int i = (idx[r] - 1) * blen + 1; i <= r; i++){
				ans += fun(value[i], add[idx[i]]);
			}
		}
		//连续块
		for (int i = idx[l] + 1; i < idx[r]; i++){
			ans += sum[i];
		}
		return ans;
	}
private:
	vector<int> idx;
	vector<ll>  sum,value,add;
	int n,blen;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值