#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
typedef pair<int, int> PII;
typedef pair<int, PII> PIII;
typedef long long ll;
const int N = 100010;
int n, mod;
int a[N];
struct Node
{
int l, r;
ll sum;
ll mul, add;
}tr[N * 4];
void pushup(int u)
{
tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum) % mod;
}
void build(int u, int l, int r)
{
if(l == r)
{
tr[u] = {l, r, a[l], 1, 0};
return;
}
tr[u] = {l, r, 0, 1, 0};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void pushdown(int u)
{
auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
left.sum = (left.sum * root.mul + root.add * (left.r - left.l + 1)) % mod;
left.mul = left.mul * root.mul % mod;
left.add = left.add * root.mul % mod;
left.add = (left.add + root.add) % mod;
right.sum = (right.sum * root.mul + root.add * (right.r - right.l + 1)) % mod;
right.mul = right.mul * root.mul % mod;
right.add = right.add * root.mul % mod;
right.add = (right.add + root.add) % mod;
root.mul = 1, root.add = 0;
}
void modify(int u, int l, int r, ll c, int op)
{
if(l <= tr[u].l && tr[u].r <= r)
{
if(op == 1)//乘
{
tr[u].sum = (tr[u].sum * c) % mod;
tr[u].mul = (tr[u].mul * c) % mod;
tr[u].add = (tr[u].add * c) % mod;
}
else
{
tr[u].sum = (tr[u].sum + c * (tr[u].r - tr[u].l + 1)) % mod;
tr[u].add = (tr[u].add + c) % mod;
}
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid)modify(u << 1, l, r, c, op);
if(mid + 1 <= r)modify(u << 1 | 1, l, r, c, op);
pushup(u);
}
ll query(int u, int l, int r)
{
if(l <= tr[u].l && tr[u].r <= r)
{
return tr[u].sum;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
ll res = 0;
if(l <= mid)res += query(u << 1, l, r);
if(mid + 1 <= r)res += query(u << 1 | 1, l, r);
pushup(u);
return res % mod;
}
int main()
{
IOS
cin >> n >> mod;
for(int i = 1; i <= n; i ++)cin >> a[i];
build(1, 1, n);
int m;
cin >> m;
while(m --)
{
int op, l, r;
ll c;
cin >> op >> l >> r;
if(op == 1)//[l, r]范围内*c
{
cin >> c;
modify(1, l, r, c, 1);
}
else if(op == 2)//[l, r]范围内+c
{
cin >> c;
modify(1, l, r, c, 2);
}
else//[l, r]范围内的和%mod
{
cout << query(1, l, r) << endl;
}
}
return 0;
}
模板 - 区间乘&区间加
最新推荐文章于 2024-09-04 21:39:45 发布