感觉是先加后乘出的问题,不知道在哪里,求调
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e5+9;
ll n,m,mod,a[N],op,x,y,k;
struct Segment_tree {
ll l,r;
ll add,mtp;
ll sum;
#define l(x) t[x].l
#define r(x) t[x].r
#define add(x) t[x].add
#define mtp(x) t[x].mtp
#define sum(x) t[x].sum
} t[4 * N];
void build(ll p, ll l, ll r)
{
l(p) = l,r(p) = r;
if (l == r)
{
sum(p) = a[l] % mod;
mtp(p) = 1;
return;
}
ll mid = l + r >> 1;
build(p * 2, l, mid);
build(p * 2 + 1, mid + 1, r);
sum(p) = (sum(2 * p) + sum(2 * p + 1)) % mod;
mtp(p) = 1;
}
void pushdown(ll p)
{
if (mtp(p) > 1)
{
sum(2 * p) = sum(2 * p) * mtp(p) % mod;
sum(2 * p + 1) = sum(2 * p + 1) * mtp(p) % mod;
add(2 * p) = add(2 * p) * mtp(p) % mod;
add(2 * p + 1) = add(2 * p + 1) * mtp(p) % mod;
mtp(2 * p) = mtp(2 * p) * mtp(p) % mod;
mtp(2 * p + 1) = mtp(2 * p + 1) * mtp(p) % mod;
mtp(p) = 1;
}
if (add(p))
{
sum(2 * p) = (sum(2 * p) + add(p) * (r(2 * p) - l(2 * p) + 1)) % mod;
sum(2 * p + 1) = (sum(2 * p + 1) + add(p) * (r(2 * p + 1) - l(2 * p + 1) + 1)) % mod;
add(2 * p) = (add(2 * p) + add(p)) % mod;
add(2 * p + 1) = (add(2 * p + 1) + add(p)) % mod;
add(p) = 0;
}
}
void modify_add(ll p, ll l, ll r, ll v)
{
if (l <= l(p) && r >= r(p))
{
sum(p) = (sum(p) + v * (r(p) - l(p) + 1)) % mod;
add(p) = (add(p) + v) % mod;
return;
}
pushdown(p);
ll mid = l(p) + r(p) >> 1;
if (l <= mid) modify_add(2 * p, l, r, v);
if (r > mid) modify_add(2 * p + 1, l, r, v);
sum(p) = (sum(2 * p) + sum(2 * p + 1)) % mod;
}
void modify_mtp(ll p, ll l, ll r, ll v)
{
if (l <= l(p) && r >= r(p))
{
sum(p) = sum(p) * v % mod;
add(p) = add(p) * v % mod;
mtp(p) = mtp(p) * v % mod;
return;
}
pushdown(p);
ll mid = l(p) + r(p) >> 1;
if (l <= mid) modify_mtp(2 * p, l, r, v);
if (r > mid) modify_mtp(2 * p + 1, l, r, v);
sum(p) = (sum(2 * p) + sum(2 * p + 1)) % mod;
}
ll query(ll p, ll l, ll r)
{
if (l <= l(p) && r >= r(p)) return sum(p);
pushdown(p);
ll mid = l(p) + r(p) >> 1;
ll ret = 0;
if (l <= mid) ret += query(2 * p, l, r);
if (r > mid) ret += query(2 * p + 1, l, r);
return ret % p;
}
int main()
{
cin >> n >> m >> mod;
for (ll i = 1; i <= n; ++i) cin >> a[i];
build(1, 1, n);
while (m--)
{
cin >> op;
if (op == 1)
{
cin >> x >> y >> k;
modify_mtp(1, x, y, k);
}
else if (op == 2)
{
cin >> x >> y >> k;
modify_add(1, x, y, k);
}
else
{
cin >> x >> y;
cout << query(1, x, y) << endl;
}
}
return 0;
}