You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int n, m, p;
// 线段树模板
#define LL long long
#define ls u << 1
#define rs u << 1 | 1
#define mid ((l + r) >> 1)
struct Node {
int l, r;
int mu, add;
LL sum;
} tr[N << 2];
void pushup(int u) {
tr[u].sum = (tr[ls].sum + tr[rs].sum) % p;
}
void build(int u, int l, int r) {
tr[u].l = l, tr[u].r = r, tr[u].mu = 1;
if (l == r) {
cin >> tr[u].sum;
return;
}
build(ls, l, mid), build(rs, mid + 1, r);
pushup(u);
}
void pushdown(int u) {
if (tr[u].add == 0 && tr[u].mu == 1) return; // 默认懒标记
int &mu = tr[u].mu, &add = tr[u].add; // 此时的add懒标记已经处理过了
tr[ls].sum = ((LL)mu * tr[ls].sum % p + (LL)(tr[ls].r - tr[ls].l + 1) * add % p) % p;
tr[rs].sum = ((LL)mu * tr[rs].sum % p + (LL)(tr[rs].r - tr[rs].l + 1) * add % p) % p;
tr[ls].mu = (LL)tr[ls].mu * mu % p;
tr[rs].mu = (LL)tr[rs].mu * mu % p;
tr[ls].add = ((LL)tr[ls].add * mu % p + add) % p;
tr[rs].add = ((LL)tr[rs].add * mu % p + add) % p;
mu = 1, add = 0; // 清空懒标记
}
void add(int u, int L, int R, int v) {
int l = tr[u].l, r = tr[u].r;
if (l >= L && r <= R) {
tr[u].add = ((LL)tr[u].add + v) % p;
tr[u].sum = ((LL)tr[u].sum + v * ((LL)tr[u].r - tr[u].l + 1) % p) % p;
return;
}
if (l > R || r < L) return;
pushdown(u);
add(ls, L, R, v), add(rs, L, R, v);
pushup(u);
}
void mu(int u, int L, int R, int v) {
int l = tr[u].l, r = tr[u].r;
if (l >= L && r <= R) {
tr[u].add = (LL)tr[u].add * v % p; // 比较重要的一步,add要在这里乘上v,因为后面可能要加其他的数而那些数其实是不用乘k的
tr[u].mu = (LL)tr[u].mu * v % p;
tr[u].sum = (LL)tr[u].sum * v % p;
return;
}
if (l > R || r < L) return;
pushdown(u);
mu(ls, L, R, v), mu(rs, L, R, v);
pushup(u);
}
LL query(int u, int L, int R) {
int l = tr[u].l, r = tr[u].r;
if (l >= L && r <= R) return tr[u].sum;
if (l > R || r < L) return 0;
pushdown(u);
return (query(ls, L, R) + query(rs, L, R)) % p;
}
signed main() {
// 文件输入输出
#ifndef ONLINE_JUDGE
freopen("P3373.in", "r", stdin);
#endif
// 加快读入
ios::sync_with_stdio(false), cin.tie(0);
cin >> n >> m >> p;
build(1, 1, n);
while (m--) {
int op, l, r;
cin >> op >> l >> r;
if (op == 1) {
int k;
cin >> k;
mu(1, l, r, k);
} else if (op == 2) {
int k;
cin >> k;
add(1, l, r, k);
} else
printf("%lld\n", query(1, l, r));
}
return 0;
}