线段树模板

线段树模板。

链接

Luogu 3373

代码

#include <cstdio>

typedef long long ll;

const int SIZE = 100005;

inline char gc() {
	static char buf[SIZE], *p1 = buf + SIZE, *p2 = buf + SIZE;
	if (p1 == p2) p2 = (p1 = buf) + fread(buf, 1, SIZE, stdin);
	return p1 == p2 ? -1 : *p1++;
}

inline ll read() {
	char ch = 0;
	ll sum = 0, s = 1;
	while (!(ch >= '0' && ch <= '9')) if ((ch = gc()) == '-') s = -1;
	while (ch >= '0' && ch <= '9') sum = (sum << 3) + (sum << 1) + ch - 48, ch = gc();
	return sum * s;
}

ll n, m, opt;
ll P, num[SIZE];
struct SegTree {
	ll r, l, add;
	ll sum, mul;
};
SegTree tree[SIZE << 2];

inline void pushDown(ll p);
inline ll ask(ll p, ll l, ll r);
inline void build(ll p, ll l, ll r);
inline void initNode(ll p, ll l, ll r);
inline void mulChange(ll p, ll l, ll r, ll k);
inline void addChange(ll p, ll l, ll r, ll k);

inline void pushDown(ll p) {
	if (tree[p].add || tree[p].mul != 1) {
		tree[p << 1].sum = (tree[p << 1].sum * tree[p].mul) % P;
		tree[p << 1 | 1].sum = (tree[p << 1 | 1].sum * tree[p].mul) % P;
		tree[p << 1].sum = (tree[p << 1].sum + (tree[p << 1].r - tree[p << 1].l + 1) * tree[p].add) % P;
		tree[p << 1 | 1].sum = (tree[p << 1 | 1].sum + (tree[p << 1 | 1].r - tree[p << 1 | 1].l + 1) * tree[p].add) % P;
		tree[p << 1].mul = (tree[p << 1].mul * tree[p].mul) % P;
		tree[p << 1 | 1].mul = (tree[p << 1 | 1].mul * tree[p].mul) % P;
		tree[p << 1].add = (tree[p].add + (tree[p << 1].add * tree[p].mul)) % P;
		tree[p << 1 | 1].add = (tree[p].add + (tree[p << 1 | 1].add * tree[p].mul)) % P;
		tree[p].add = 0, tree[p].mul = 1;
	}
	return;
}

inline ll ask(ll p, ll l, ll r) {
	if (l <= tree[p].l && tree[p].r <= r) {
		return tree[p].sum % P;
	}
    pushDown(p);
	ll res = 0, mid = (tree[p].l + tree[p].r) >> 1;
	if (l <= mid) res = res + ask(p << 1, l, r);
	if (r > mid) res = res + ask(p << 1 | 1, l, r);
	return res % P;
}

inline void build(ll p, ll l, ll r) {
	initNode(p, l, r);
	if (l == r) {
		tree[p].sum = num[l];
		return;
	}
	ll mid = (l + r) >> 1;
	build(p << 1, l, mid);
	build(p << 1 | 1, mid + 1, r);
	tree[p].sum = (tree[p << 1].sum + tree[p << 1 | 1].sum) % P;
}

inline void initNode(ll p, ll l, ll r) {
	tree[p].add = 0, tree[p].mul = 1;
	tree[p].l = l, tree[p].r = r;
}

inline void mulChange(ll p, ll l, ll r, ll k) {
	if (l <= tree[p].l && tree[p].r <= r) {
		tree[p].mul = (tree[p].mul * k) % P;
		tree[p].add = (tree[p].add * k) % P;
		tree[p].sum = (tree[p].sum * k) % P;
		return;
	}
	pushDown(p);
	ll mid = (tree[p].l + tree[p].r) >> 1;
	if (l <= mid) mulChange(p << 1, l, r, k);
	if (r > mid) mulChange(p << 1 | 1, l, r, k);
	tree[p].sum = (tree[p << 1].sum + tree[p << 1 | 1].sum) % P;
	return;
}

inline void addChange(ll p, ll l, ll r, ll k) {
	if (l <= tree[p].l && tree[p].r <= r) {
		tree[p].sum = (tree[p].sum + (tree[p].r - tree[p].l + 1) * k) % P;
		tree[p].add = (tree[p].add + k % P) % P;
		return;
	}
	pushDown(p);
	ll mid = (tree[p].l + tree[p].r) >> 1;
	if (l <= mid) addChange(p << 1, l, r, k);
	if (r > mid) addChange(p << 1|1, l, r, k);
	tree[p].sum = (tree[p << 1].sum + tree[p << 1 | 1].sum) % P;
	return;
}

int main() {
	ll opt, a, b, k;
	n = read(), m = read(), P = read();
	for (ll i = 1; i <= n; i++) num[i] = read();
	build(1, 1, n);
	for (ll i = 1; i <= m; i++) {
		opt = read(), a = read(), b = read();
		if (opt == 1) k = read(), mulChange(1, a, b, k);
		if (opt == 2) k = read(), addChange(1, a, b, k);
		if (opt == 3) printf("%lld
", (ask(1, a, b) % P + P) % P);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/lcfsih/p/14391367.html