线段树30分求助,只过了1,3,4
查看原帖
线段树30分求助,只过了1,3,4
432813
a1187153633楼主2021/9/13 21:58
#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 9e5 + 10;

LL n, m, mod, a[N], ans[N], multag[N], addtag[N];

inline void build(LL p, LL l, LL r)
{
	addtag[p] = 0;
	multag[p] = 1;
	if (l == r)
	{
		ans[p] = a[l];
		return;
	}
	LL mid = l + r >> 1;
	
	build(p << 1, l, mid);
	build(p << 1 | 1, mid + 1, r);

	ans[p] = (ans[p << 1] + ans[p << 1 | 1]) % mod;
	return;
}


inline void push_down(LL p, LL l, LL r)
{
	LL mid = l + r >> 1;
	
	ans[p << 1] = (ans[p << 1] * multag[p] + addtag[p] * (mid - l + 1)) % mod;
	ans[p << 1 | 1] = (ans[p << 1 | 1] * multag[p] + addtag[p] * (r - mid)) % mod;

	multag[p << 1] = (multag[p << 1] * multag[p]) % mod;
	multag[p << 1 | 1] = (multag[p << 1 | 1] * multag[p]) % mod;
	
	addtag[p << 1] = (addtag[p << 1] * multag[p] + addtag[p]) % mod;
	addtag[p << 1 | 1] = addtag[p << 1 | 1] * multag[p] + addtag[p] % mod;
	
	multag[p] = 1;
	addtag[p] = 0;
	return;	
}

inline void update_1(LL nl, LL nr, LL l, LL r, LL p, LL k)
{
	if (r < nl || l > nr) return;

	if (nl <= l && r <= nr)
	{
		ans[p] = (ans[p] * k) % mod;
		multag[p] = (multag[p] * k) % mod;
		addtag[p] = (addtag[p] * k) % mod;
		return;	
	}

	push_down(p, l, r);
	LL mid = l + r >> 1;
	update_1(nl, nr, l, mid, p << 1, k);
	update_1(nl, nr, mid + 1, r, p << 1 | 1, k);

	ans[p] = ans[p << 1] + ans[p << 1 | 1];

	return;
}

inline void update_2(LL nl, LL nr, LL l, LL r, LL p, LL k)
{
	if (nl <= l && r <= nr)
	{
		addtag[p] = (addtag[p] + k) % mod;
		ans[p] = (ans[p] + k * (r - l + 1)) % mod;
		return;
	}

	push_down(p, l, r);

	LL mid = l + r >> 1;

	if (nl <= mid) update_2(nl, nr, l, mid, p << 1, k);
	if (nr > mid) update_2(nl, nr, mid + 1, r, p << 1 | 1, k);

	ans[p] = (ans[p << 1] + ans[p << 1 | 1]) % mod;
}
LL query(LL q_x, LL q_y, LL l, LL r, LL p)
{
	if (q_x <= l && r <= q_y) return ans[p];

	LL mid = l + r >> 1;
	LL res = 0;

	push_down(p, l, r);
	
	if (q_x <= mid) res = (res + query(q_x, q_y, l, mid, p << 1)) % mod;
	if (q_y > mid) res = (res + query(q_x, q_y, mid + 1, r, p << 1 | 1)) % mod;

	return res;
}

int main()
{
	scanf("%lld%lld%lld", &n, &m,&mod);

	for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);

	build(1, 1, n);

	while (m--)
	{
		LL t, x, y, k;
		scanf("%lld", &t);
		if (t == 1)
		{
			scanf("%lld%lld%lld", &x, &y, &k);
			update_1(x, y, 1, n, 1, k);
		}
		else if (t == 2)
		{
			scanf("%lld%lld%lld", &x, &y,&k);
			update_2(x, y, 1, n, 1, k);
		}
		else
		{
			scanf("%lld%lld", &x, &y);
			printf("%lld\n",query(x, y, 1, n, 1));
		}
	}

	return 0;
}

queryqueryupdate2update2来源线段树模板1,因为我不会文件读入..下载了case2的样例我也不知道怎么导入进去...求大佬帮忙ORZ

2021/9/13 21:58
加载中...