代码如下()
#include <stdint.h>
#include <iostream>
using namespace std;
const int N = 1e6 + 10;
int n, m;
int MOD;
int w[N];
struct Node
{
int l, r;
int sum, add, mul;
}tree[4 * N];
int left_son(int u)
{
return (u << 1);
}
int right_son(int u)
{
return (u << 1) | 1;
}
void push_up(int u)
{
tree[u].sum = (tree[left_son(u)].sum + tree[right_son(1)].sum) % MOD;
}
void eval(Node &t, int add, int mul)
{
t.sum = ((int64_t)t.sum * mul + (int64_t)(t.r - t.l + 1) * add) % MOD;
t.mul = ((int64_t)t.mul * mul) % MOD;
t.add = ((int64_t)t.add * mul + add) % MOD;
}
void build(int u, int l, int r)
{
if(l == r) tree[u] = (Node){l, r, w[r], 0, 1};
else
{
tree[u] = (Node){l, r, 0, 0, 1};
int mid = (l + r) / 2;
build(left_son(u), l, mid);
build(right_son(u), mid + 1, r);
push_up(u);
}
}
void push_down(int u)
{// 先乘再加
eval(tree[left_son(u)], tree[u].add, tree[u].mul);
eval(tree[right_son(u)], tree[u].add, tree[u].mul);
tree[u].add = 0;
tree[u].mul = 1;
}
void modify(int u, int l, int r, int add, int mul)
{
if(tree[u].l >= l and tree[u].r <= r)
{
eval(tree[u], add, mul);
}
else
{
push_down(u);
int mid = (tree[u].l + tree[u].r) >> 1;
if(l <= mid) modify(left_son(u), l, r, add, mul);
if(r > mid) modify(right_son(u), l, r, add, mul);
push_up(u);
}
}
int query(int u, int l, int r)
{
if(tree[u].l >= l and tree[u].r <= r) return tree[u].sum;
push_down(u);
int mid = (tree[u].l + tree[u].r) / 2;
int sum = 0;
if(l <= mid) sum += query(left_son(u), l, r) % MOD;
sum %= MOD;
if(r > mid) sum += query(right_son(u), l, r) % MOD;
sum %= MOD;
return sum;
}
int op, l, r, c;
int main()
{
scanf("%d %d", &n, &MOD);
for(int i = 1;i <= n;i ++) scanf("%d", &w[i]);
build(1, 1, n);
scanf("%d", &m);
while(m--)
{
scanf("%d%d%d",&op, &l, &r);
if(op == 1)
{
scanf("%d", &c);
modify(1, l, r, c, 0);
}else if(op == 2)
{
scanf("%d", &c);
modify(1, l, r, 1, c);
}
else if(op == 3)
{
printf("%d\n", query(1, l, r));
}
}
return 0;
}