线段树模板。
链接
代码
#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;
}