【违规不仅自杀还杀了想出这玩意的人】线段树求调
查看原帖
【违规不仅自杀还杀了想出这玩意的人】线段树求调
341741
int114514楼主2021/7/26 22:47

qwq 线段树 2 调不出来了,蒟蒻急死了……

代码(发的比较急所以没注释):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN = 114514;
ll a[MAXN], d[MAXN << 2], tag1[MAXN << 2], tag2[MAXN << 2], n, m, MOD, opt, x, y, k;
ll read() {
	ll x = 0, fl = 1; char ch = getchar();
	while(!isdigit(ch)) {if(ch == '-') fl = -1; ch = getchar();}
	while(isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();}
	return fl * x;
}
inline void pushup(ll p) {
	d[p] = (d[p << 1] + d[p << 1 | 1]) % MOD;
}
void pushdown(ll p, ll s, ll t) {
	ll m = s + t >> 1;
	d[p << 1] = (d[p << 1] * tag2[p] % MOD + tag1[p] * (m - s + 1) % MOD) % MOD;
	d[p << 1 | 1] = (d[p << 1 | 1] * tag2[p] % MOD + tag1[p] * (t - s) % MOD) % MOD;
	tag2[p << 1] = tag2[p << 1] * tag2[p] % MOD;
	tag2[p << 1 | 1] = tag2[p << 1 | 1] * tag2[p] % MOD;
	tag1[p << 1] = (tag1[p << 1] * tag2[p] + tag1[p]) % MOD;
	tag1[p << 1 | 1] = (tag1[p << 1 | 1] * tag2[p] + tag1[p]) % MOD;
	tag1[p] = 0, tag2[p] = 1;
}
void build(ll l, ll r, ll p) {
	tag2[p] = 1;
	if(l == r) {
		d[p] = a[l] % MOD;
		return ;
	}
	ll m = l + r >> 1;
	build(l, m, p << 1);
	build(m + 1, r, p << 1 | 1);
	pushup(p);
}
void update1(ll l, ll r, ll s, ll t, ll c, ll p) {
	if(l <= s && t <= r) {
		d[p] = (d[p] + (t-s+1) * c) % MOD;
		tag1[p] = (tag1[p] + c) % MOD;
		return ;
	}
	ll m = s + t >> 1;
	if(s != t) pushdown(p, s, t);
	if(l <= m) update1(l, r, s, m, c, p << 1);
	if(m < r) update1(l, r, m + 1, t, c, p << 1 | 1);
	pushup(p);
}
void update2(ll l, ll r, ll s, ll t, ll c, ll p) {
	if(l <= s && t <= r) {
		d[p] = (d[p] * c) % MOD;
		tag1[p] = (tag1[p] * c) % MOD;
		tag2[p] = (tag2[p] * c) % MOD;
		return ;
	}
	ll m = s + t >> 1;
	if(s != t) pushdown(p, s, t);
	if(l <= m) update2(l, r, s, m, c, p << 1);
	if(m < r) update2(l, r, m + 1, t, c, p << 1 | 1);
}
ll query(ll l, ll r, ll s, ll t, ll p) {
	if(l <= s && t <= r) return d[p];
	ll m = s + t >> 1;
	if(s != t) pushdown(p, s, t);
	ll ans = 0;
	if(l <= m) ans = (ans + query(l, r, s,  m, p << 1)) % MOD;
	if(m < r) ans = (ans + query(l, r, m + 1, t, p << 1 | 1)) % MOD;
	return ans;
}

int main() {
	n = read(); m = read(); MOD = read();
	for(int i = 1; i <= n; i++) a[i] = read();
	while(m--) {
		opt = read();
		switch(opt) {
			case 1:
				x = read(); y = read(); k = read();
				update2(x, y, 1, n, k, 1);
				break;
			case 2:
				x = read(); y = read(); k = read();
				update1(x, y, 1, n, k, 1);
				break;
			case 3:
				x = read(); y = read();
				//for(int i = 1; i <= (n << 2); i++) cout << d[i] << ' ';
				//puts("");
				printf("%d\n", query(x, y, 1, n, 1));
				break;
		}
	}
	return 0;
}

成功解决者将获得大号+小号的关注。

2021/7/26 22:47
加载中...