社区讨论

qz,30pts

P3373【模板】线段树 2参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lu3nqn3k
此快照首次捕获于
2024/03/23 13:36
2 年前
此快照最后确认于
2024/03/23 15:42
2 年前
查看原帖
CPP
#include <iostream>
#include <cstdio>
using namespace std;
struct segment_tree
{
	int l, r;
	long long value;
	int tag1, tag2;	
};
const int maxn = 1E5 + 5;
long long a[maxn];
segment_tree tree[maxn * 4];
int n, q;
long long m;
void pushup(int root)
{
	tree[root].value = (tree[root << 1].value + tree[(root << 1) + 1].value) % m;
}
void build(int root, int l, int r)
{
	tree[root].tag1 = 0, tree[root].tag2 = 1;
	tree[root].l = l, tree[root].r = r;
	if(l == r)
	{
		tree[root].value = a[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(root << 1, l, mid);
	build((root << 1) + 1, mid + 1, r);
	pushup(root);
	
}
void maketag(int root, long long x, int op)
{
	int l = tree[root].l, r = tree[root].r;
	if(op == 1)
	{
		tree[root].tag1 += x, tree[root].tag1 %= m;
		tree[root].value += (r - l + 1) * x, tree[root].value %= m;
	}
	else
	{
		tree[root].tag1 *= x, tree[root].tag2 *= x;
		tree[root].tag1 %= m, tree[root].tag2 %= m;
		tree[root].value *= x;
		tree[root].value %= m;
	}
}
void pushdown(int root)
{
	maketag(root << 1, tree[root].tag2, 0);
	maketag(root << 1, tree[root].tag1, 1);
	maketag((root << 1) + 1, tree[root].tag2, 0);
	maketag((root << 1) + 1, tree[root].tag1, 1);
	tree[root].tag1 = 0, tree[root].tag2 = 1;
}
void update(int root, int L, int R, long long x, int op)
{
	int l = tree[root].l, r = tree[root].r;
	if(L <= l && r <= R)
	{
		maketag(root, x, op);
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(root);
	if(L <= mid) update(root << 1, L, R, x, op);
	if(R > mid) update((root << 1) + 1, L, R, x, op);
	pushup(root);
}
long long query(int root, int L, int R)
{
	int l = tree[root].l, r = tree[root].r;
	if(L <= l && r <= R) return tree[root].value;
	int mid = (l + r) >>  1;
	long long res = 0;
	pushdown(root);
	if(L <= mid) (res += query(root << 1, L, R)) % m;
	if(R > mid) (res += query((root << 1) + 1, L, R)) % m;
	return res % m;
}
int main()
{
	scanf("%d%d%d", &n, &q, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &a[i]);
		a[i] %= m;
	}
	build(1, 1, n);
	while(q--)
	{
		int opt;
		scanf("%d", &opt);
		if(opt == 1)
		{
			int x, y;
			long long k;
			scanf("%d%d%lld", &x, &y, &k);
			k %= m;
			update(1, x, y, k, 0);
		}
		else
		{
			if(opt == 2)
			{
				int x, y;
				long long k;
				scanf("%d%d%lld", &x, &y, &k);
				k %= m;
				update(1, x, y, k, 1);
			}
			else
			{
				int x, y;
				scanf("%d%d", &x, &y);
				printf("%lld\n", query(1, x, y) % m);
			}
		}
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...