社区讨论

史山样例过不了 求dalao看看

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

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@m04176vk
此快照首次捕获于
2024/08/21 23:51
2 年前
此快照最后确认于
2025/11/04 22:48
4 个月前
查看原帖
我估计就是pushdown和xg的问题
CPP
#include <bits/stdc++.h>
using namespace std;

long long Tr[600005], add[600005], times[600005], mod;
int n, m;

void pushdown(int rt, int l, int r){
	if (l == r)	return ;
	int mid = (l + r) >> 1, ls = rt << 1, rs = rt << 1 | 1;
	Tr[ls] = (Tr[ls] * times[rt] + (m - l + 1) * add[rt]) % mod;
	Tr[rs] = (Tr[rs] * times[rt] + (r - m) * add[rt]) % mod;
	
	times[ls] = (times[ls] * times[rt]) % mod;times[rs] = (times[rs] * times[rt]) % mod;
	add[ls] = (add[ls] * times[rt] + add[rt]) % mod, add[rs] = (add[rs] * times[rt] + add[rt]) % mod;
	times[rt] = 1;add[rt] = 0;
}

void xg(int rt, int l, int r, int ql, int qr, long long x, long long y){
	if (ql <= l && r <= qr){
		Tr[rt] = (Tr[rt] * y + (r - l + 1) * x) % mod;
		times[rt] = (times[rt] * y) % mod;
		add[rt] = (add[rt] * y + x) % mod;
		return ;
	}
	pushdown(rt, l, r);
	int mid = (l + r) >> 1;
	if (ql <= mid)	xg(rt << 1, l, mid, ql, qr, x, y);
	if (mid < qr)	xg(rt << 1 | 1, mid + 1, r, ql, qr, x, y);
	Tr[rt] = Tr[rt << 1] + Tr[rt << 1 | 1];
	Tr[rt] %= mod;
}

long long xw(int rt, int l, int r, int ql, int qr){
	if (qr < l || r < ql)	return 0;
	if (ql <= l && r <= qr)
		return Tr[rt];
	
	pushdown(rt, l, r);
	int mid = (l + r) >> 1;
	return (xw(rt << 1, l, mid, ql, qr) + xw(rt << 1 | 1, mid + 1, r, ql, qr)) % mod;
}

int main(){
	cin >> n >> m >> mod;
	
	for (int i = 0; i <= 600000; i ++)	times[i] = 1;
	for (int i = 1; i <= n; i ++){
		long long a;scanf("%lld", &a);
		xg(1, 1, n, i, i, a, 1);
	}
	
	while (m --){
		int c, x, y;
		scanf("%d%d%d", &c, &x, &y);
		if (c == 1){
			long long k;scanf("%lld", &k);
			xg(1, 1, n, x, y, 0, k);
		}if (c == 2){
			long long k;scanf("%lld", &k);
			xg(1, 1, n, x, y, k, 1);
		}if (c == 3)	printf("%lld\n", xw(1, 1, n, x, y));
	}
	
	return 0;
}

回复

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

正在加载回复...