如何使用标记永久化?
查看原帖
如何使用标记永久化?
670992
Planaria楼主2023/1/7 20:13

错误代码,求调:

#include <cstdio>

const int maxn = 100001, mod = 38;

struct Segment {
	int val, add, mul, lch, rch;
};

int cnt;
int arr[maxn];
Segment seg[maxn << 1];


int max(const int x, const int y) {
	return x > y ? x : y;
}

int min(const int x, const int y) {
	return x < y ? x : y;
}

void pushup(int left, int right, int root) {
	seg[root].val = (seg[seg[root].lch].val + seg[seg[root].rch].val + seg[root].add * (right - left + 1)) % mod;
}

void build(int left, int right, int& root) {
	if (!root) root = ++cnt;
	seg[root].add = 0;
	seg[root].mul = 1;
	if (left == right) {
		seg[root].val = arr[left] % mod;
		return;
	}
	int mid = left + ((right - left) >> 1);
	build(left, mid, seg[root].lch);
	build(mid + 1, right, seg[root].rch);
	pushup(left, right, root);
}

void addition(int low, int high, int val, int left, int right, int& root) {
	if (!root) root = ++cnt;
	if (low <= left && right <= high) {
		seg[root].val = (seg[root].val + val * (right - left + 1)) % mod;
		seg[root].add = (seg[root].add + val) % mod;
		return;
	}
	int mid = left + ((right - left) >> 1);
	if (low <= mid) addition(low, high, val, left, mid, seg[root].lch);
	if (high > mid) addition(low, high, val, mid + 1, right, seg[root].rch);
	pushup(left, right, root);
}

void multiplication(int low, int high, int val, int left, int right, int& root) {
	if (!root) root = ++cnt;
	if (low <= left && right <= high) {
		seg[root].val = (seg[root].val * val) % mod;
		seg[root].mul = (seg[root].mul * val) % mod;
		seg[root].add = (seg[root].add * val) % mod;
		return;
	}
	int mid = left + ((right - left) >> 1);
	if (low <= mid) multiplication(low, high, val, left, mid, seg[root].lch);
	if (high > mid) multiplication(low, high, val, mid + 1, right, seg[root].rch);
	pushup(left, right, root);
}

int getsum(int low, int high, int left, int right, int root) {
	if (!root) return 0;
	if (low <= left && right <= high) return seg[root].val;
	int mid = left + ((right - left) >> 1);
	int sum = (seg[root].add * (min(high, right) - max(low, left) + 1)) % mod;
	if (low <= mid) sum = (sum + getsum(low, high, left, mid, seg[root].lch)) % mod;
	if (high > mid) sum = (sum + getsum(low, high, mid + 1, right, seg[root].rch)) % mod;
	return sum;
}

int main() {
	int n, m, rt = 0;
	scanf("%d%d%*d", &n, &m);
	for (int i = 1; i <= n; ++i) scanf("%d", arr + i);

	build(1, n, rt);

	for (; m; --m) {
		int op, x, y, k;
		scanf("%d%d%d", &op, &x, &y);
		switch (op) {
			case 1:
				scanf("%d", &k);
				multiplication(x, y, k, 1, n, rt);
				break;
			case 2:
				scanf("%d", &k);
				addition(x, y, k, 1, n, rt);
				break;
			default:
				printf("%d\n", getsum(x, y, 1, n, rt));
				break;
		}
	}

	return 0;
}
2023/1/7 20:13
加载中...