#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define ll long long
using namespace std;
const int N = 2e5 + 10;
ll a[N];
ll n, m, p;
struct node
{
ll l, r, res, sum, mull;
} tr[N << 2];
void pushdown(ll u)
{
node &f = tr[u],
&l = tr[u << 1],
&r = tr[u << 1 | 1];
l.res = (l.res * f.mull + f.sum * (l.r - l.l + 1)) % p;
r.res = (r.res * f.mull + f.sum * (r.r - r.l + 1)) % p;
l.sum = (l.sum * f.mull + f.sum) % p;
r.sum = (r.sum * f.mull + f.sum) % p;
l.mull = (l.mull * f.mull) % p;
r.mull = (r.mull * f.mull) % p;
f.mull = 1, f.sum = 0;
}
void pushup(ll u)
{
tr[u].res = (tr[u << 1].res + tr[u << 1 | 1].res) % p;
}
void build(ll u, ll l, ll r)
{
if (l == r)
{
tr[u] = {l, r, a[r] % p, 0, 1};
return;
}
tr[u] = {l, r, 0, 0, 1};
ll mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void mul(ll u, ll l, ll r, ll k)
{
if (tr[u].l >= l && tr[u].r <= r)
{
tr[u].mull = (tr[u].mull * k) % p;
tr[u].sum = (tr[u].sum * k) % p;
tr[u].res = (tr[u].res * k) % p;
return;
}
pushdown(u);
ll mid = tr[u].l + tr[u].r >> 1;
if (l <= mid)
mul(u << 1, l, r, k);
if (r > mid)
mul(u << 1 | 1, l, r, k);
pushup(u);
}
void add(ll u, ll l, ll r, ll k)
{
if (tr[u].l >= l && tr[u].r <= r)
{
tr[u].sum = (tr[u].sum + k) % p;
tr[u].res = (tr[u].res + (tr[u].r - tr[u].l + 1) * k) % p;
return;
}
pushdown(u);
ll mid = tr[u].l + tr[u].r >> 1;
if (l <= mid)
add(u << 1, l, r, k);
if (r > mid)
add(u << 1 | 1, l, r, k);
pushup(u);
}
ll query(ll u, ll l, ll r)
{
if (tr[u].l >= l && tr[u].r <= r)
return tr[u].res;
pushdown(u);
ll ans = 0;
ll mid = tr[u].l + tr[u].r >> 1;
if (l <= mid)
ans = (ans + query(u << 1, l, r)) % p;
if (r > mid)
ans = (ans + query(u << 1 | 1, l, r)) % p;
return ans;
}
int main()
{
cin >> n >> m >> p;
for (ll i = 1; i <= n; i++)
cin >> a[i];
build(1, 1, n);
for (ll i = 1; i <= m; i++)
{
ll t;
cin >> t;
if (t == 1)
{
ll x, y, k;
cin >> x >> y >> k;
mul(1, x, y, k);
}
else if (t == 2)
{
ll x, y, k;
cin >> x >> y >> k;
add(1, x, y, k);
}
else
{
ll x, y;
cin >> x >> y;
cout << query(1, x, y) << endl;
}
}
return 0;
}
```在此程序中将mul,add,query这几个函数中递归调用的部分的(u<<1,l,r,)改为(u<<1,l,mid,)则只可以通过样例。但是对于u<<1这个左子树,mid=tr[u].l+tr[u].r>>1,mid不就已经够用了吗,为什么会出现问题(ps:我尝试过对mid进行+-1处理,还是不行,说明不是临界问题;且我尝试将mid换成l+1,r-1,发现依旧无法通过,说明可能函数调用必须是(u<<1,l,r,)的形式)