#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 9e5 + 10;
LL n, m, mod, a[N], ans[N], multag[N], addtag[N];
inline void build(LL p, LL l, LL r)
{
addtag[p] = 0;
multag[p] = 1;
if (l == r)
{
ans[p] = a[l];
return;
}
LL mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
ans[p] = (ans[p << 1] + ans[p << 1 | 1]) % mod;
return;
}
inline void push_down(LL p, LL l, LL r)
{
LL mid = l + r >> 1;
ans[p << 1] = (ans[p << 1] * multag[p] + addtag[p] * (mid - l + 1)) % mod;
ans[p << 1 | 1] = (ans[p << 1 | 1] * multag[p] + addtag[p] * (r - mid)) % mod;
multag[p << 1] = (multag[p << 1] * multag[p]) % mod;
multag[p << 1 | 1] = (multag[p << 1 | 1] * multag[p]) % mod;
addtag[p << 1] = (addtag[p << 1] * multag[p] + addtag[p]) % mod;
addtag[p << 1 | 1] = addtag[p << 1 | 1] * multag[p] + addtag[p] % mod;
multag[p] = 1;
addtag[p] = 0;
return;
}
inline void update_1(LL nl, LL nr, LL l, LL r, LL p, LL k)
{
if (r < nl || l > nr) return;
if (nl <= l && r <= nr)
{
ans[p] = (ans[p] * k) % mod;
multag[p] = (multag[p] * k) % mod;
addtag[p] = (addtag[p] * k) % mod;
return;
}
push_down(p, l, r);
LL mid = l + r >> 1;
update_1(nl, nr, l, mid, p << 1, k);
update_1(nl, nr, mid + 1, r, p << 1 | 1, k);
ans[p] = ans[p << 1] + ans[p << 1 | 1];
return;
}
inline void update_2(LL nl, LL nr, LL l, LL r, LL p, LL k)
{
if (nl <= l && r <= nr)
{
addtag[p] = (addtag[p] + k) % mod;
ans[p] = (ans[p] + k * (r - l + 1)) % mod;
return;
}
push_down(p, l, r);
LL mid = l + r >> 1;
if (nl <= mid) update_2(nl, nr, l, mid, p << 1, k);
if (nr > mid) update_2(nl, nr, mid + 1, r, p << 1 | 1, k);
ans[p] = (ans[p << 1] + ans[p << 1 | 1]) % mod;
}
LL query(LL q_x, LL q_y, LL l, LL r, LL p)
{
if (q_x <= l && r <= q_y) return ans[p];
LL mid = l + r >> 1;
LL res = 0;
push_down(p, l, r);
if (q_x <= mid) res = (res + query(q_x, q_y, l, mid, p << 1)) % mod;
if (q_y > mid) res = (res + query(q_x, q_y, mid + 1, r, p << 1 | 1)) % mod;
return res;
}
int main()
{
scanf("%lld%lld%lld", &n, &m,&mod);
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
build(1, 1, n);
while (m--)
{
LL t, x, y, k;
scanf("%lld", &t);
if (t == 1)
{
scanf("%lld%lld%lld", &x, &y, &k);
update_1(x, y, 1, n, 1, k);
}
else if (t == 2)
{
scanf("%lld%lld%lld", &x, &y,&k);
update_2(x, y, 1, n, 1, k);
}
else
{
scanf("%lld%lld", &x, &y);
printf("%lld\n",query(x, y, 1, n, 1));
}
}
return 0;
}
query和update2来源线段树模板1,因为我不会文件读入..下载了case2的样例我也不知道怎么导入进去...求大佬帮忙ORZ