mx分块求调
查看原帖
mx分块求调
767788
HHH6666666666楼主2022/12/12 21:27

mx刚学分块,能过3个点,不知道是哪里写挂了还是维护的正确性有问题,有没有哪位dl能帮忙看看QAQ

#include<bits/stdc++.h>
using namespace std;
#define ll long long

const int MAXN = 100010;
const int SQRTN = 330;
const int MOD = 571373;

class Partitioning{
	int len, partlen;
	int sec[MAXN];
	ll sum[MAXN], secsum[SQRTN], atag[SQRTN], mtag[SQRTN];
	inline int left(int s){ return (s - 1) * partlen + 1; }
	inline int right(int s){ return min(s * partlen, len); }
public:
	inline void setup(int n){
		len = n, partlen = sqrt(n);
		for (int i = 1; i <= len; ++i){
			scanf("%lld", &sum[i]), sum[i] %= MOD;
			sec[i] = (i - 1) / partlen + 1;
			mtag[sec[i]] = 1, atag[sec[i]] = 0;
			(secsum[sec[i]] += sum[i]) %= MOD;
		}
		return;
	}
	inline void add(int l, int r, ll k){
		if (sec[l] == sec[r]){
			for (int i = l; i <= r; ++i){
				(secsum[sec[i]] += k) %= MOD;
				(sum[i] += k) %= MOD;
			}
			return;
		}
		int e = right(sec[l]);
		for (int i = l; i <= e; ++i){
			(secsum[sec[i]] += k) %= MOD;
			(sum[i] += k) %= MOD;
		}
		for (int i = left(sec[r]); i <= r; ++i){
			(secsum[sec[i]] += k) %= MOD;
			(sum[i] += k) %= MOD;
		}
		for (int i = sec[l] + 1; i < sec[r]; ++i){
			(secsum[i] += k * (right(i) - left(i) + 1)) %= MOD;
			(atag[i] += k) %= MOD;
		}
		return;
	}
	inline void mul(int l, int r, ll k){
		if (sec[l] == sec[r]){
			for (int i = l; i <= r; ++i){
				(secsum[sec[i]] += (k - 1) * sum[i]) %= MOD;
				(sum[i] *= k) %= MOD;
			}
			return;
		}
		int e = right(sec[l]);
		for (int i = l; i <= e; ++i){
			(secsum[sec[i]] += (k - 1) * sum[i]) %= MOD;
			(sum[i] *= k) %= MOD;
		}
		for (int i = left(sec[r]); i <= r; ++i){
			(secsum[sec[i]] += (k - 1) * sum[i]) %= MOD;
			(sum[i] *= k) %= MOD;
		}
		for (int i = sec[l] + 1; i < sec[r]; ++i){
			(secsum[i] *= k) %= MOD;
			(atag[i] *= k) %= MOD;
			(mtag[i] *= k) %= MOD;
		}
		return;
	}
	inline ll query(int l, int r){
		ll res = 0;
		if (sec[l] == sec[r]){
			for (int i = l; i <= r; ++i) (res += sum[i] * mtag[sec[i]] % MOD + atag[sec[i]]) %= MOD;
			return res;
		}
		int e = right(sec[l]);
		for (int i = l; i <= e; ++i) (res += sum[i] * mtag[sec[i]] % MOD + atag[sec[i]]) %= MOD;
		for (int i = left(sec[r]); i <= r; ++i) (res += sum[i] * mtag[sec[i]] % MOD + atag[sec[i]]) %= MOD;
		for (int i = sec[l] + 1; i < sec[r]; ++i) (res += secsum[i]) %= MOD;
		return res;
	}
	inline void print(){
		for (int i = 1; i <= sec[len]; ++i){
			printf("NOW VIEWING SECTION OF %d-%d, id=%d:\n", left(i), right(i), i);
			printf("\tThe sum of each element: "); for (int j = left(i); j <= right(i); ++j) printf("%7lld", sum[j]);
			puts(""); printf("\t The section sum: %lld\n", secsum[i]);
			printf("\t The add tag and the mul tag are: %lld %lld\n", atag[i], mtag[i]);
			puts("");
		}
		puts("");
		return;
	}
};

int n, m, pp;
Partitioning p;

int main(){
	freopen("3373.in", "r", stdin);
	freopen("3373.out", "w", stdout);
	scanf("%d%d%d", &n, &m, &pp);
	p.setup(n);
	int op, x, y; ll k;
	for (int i = 1; i <= m; ++i){
		scanf("%d%d%d", &op, &x, &y);
		if (op == 1){
			scanf("%lld", &k);
			p.mul(x, y, k % MOD); 
		}
		else if (op == 2){
			scanf("%lld", &k);
			p.add(x, y, k % MOD);
		}
		else printf("%lld\n", p.query(x, y) % MOD);
		printf("OPERATION %d, info:\n", i);
		p.print();
	} 
	return 0;
}

2022/12/12 21:27
加载中...