内存池也开了,就是不过。。。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define T long long
using namespace std;
const int N = 500010, mod = 19260817;
int w[N], n, m, now;
struct Queries {
int op, l, r, x;
}q[100010];
struct node {
node *ls, *rs;
int l, r;
T sum, add, mul;
node() { ls = rs = NULL; sum = add = 0; mul = 1; }
int len() { return r - l + 1; }
void pushup() { this -> sum = (ls -> sum + rs -> sum) % mod; }
void push_add(T val) { (add += val) %= mod, (sum += this -> len() * val) %= mod; }
void push_mul(T val) { (add *= val) %= mod, (sum *= val) %= mod, (mul *= val) %= mod; }
void pushdown() {
if (mul != 1) ls -> push_mul(mul), rs -> push_mul(mul), mul = 1;
if (add) ls -> push_add(add), rs -> push_add(add), add = 0;
}
}pool[N * 4], *idx;
struct SegmentTree {
private :
node *rt;
void build(node *u, int l, int r) {
u -> l = l, u -> r = r;
if (l == r) { u -> sum = w[r] % mod; return; }
int mid = l + r >> 1;
u -> ls = new(idx ++ )node(), u -> rs = new(idx ++ )node();
build(u -> ls, l, mid), build(u -> rs, mid + 1, r);
u -> pushup();
}
void Add(node *u, int l, int r, T val) {
if (u -> l >= l && u -> r <= r) { return (void)u -> push_add(val); }
u -> pushdown();
int mid = u -> l + u -> r >> 1;
if (l <= mid) Add(u -> ls, l, r, val);
if (r > mid) Add(u -> rs, l, r, val);
u -> pushup();
}
void Mul(node *u, int l, int r, T val) {
if (u -> l >= l && u -> r <= r) { return (void)u -> push_mul(val); }
u -> pushdown();
int mid = u -> l + u -> r >> 1;
if (l <= mid) Mul(u -> ls, l, r, val);
if (r > mid) Mul(u -> rs, l, r, val);
u -> pushup();
}
T query(node *u, int l, int r) {
if (u -> l >= l && u -> r <= r) return u -> sum;
u -> pushdown();
int mid = u -> l + u -> r >> 1, ans = 0;
if (l <= mid) (ans += query(u -> ls, l, r)) %= mod;
if (r > mid) (ans += query(u -> rs, l, r)) %= mod;
return ans;
}
public :
void build() { rt = new(idx ++ )node(); build(rt, 1, n); }
void Add(int l, int r, int val) { Add(rt, l, r, val); }
void Mul(int l, int r, int val) { Mul(rt, l, r, val); }
T query(int l, int r) { return query(rt, l, r); }
}tr[2];
int main() {
idx = pool;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ )
scanf("%d", &w[i]);
tr[0].build(), tr[1].build();
q[0].op = 4;
for (int i = 1; i <= m; i ++ ) {
scanf("%d", &q[i].op);
if (q[i].op == 1) scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].x), tr[now].Add(q[i].l, q[i].r, q[i].x);
if (q[i].op == 2) scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].x), tr[now].Mul(q[i].l, q[i].r, q[i].x);
if (q[i].op == 3) scanf("%d%d", &q[i].l, &q[i].r), printf("%lld\n", tr[now].query(q[i].l, q[i].r));
if (q[i].op == 4) {
for (int j = i - 1; q[j].op != 4; j -- )
if (q[j].op == 1) tr[now ^ 1].Add(q[j].l, q[j].r, q[j].x);
else if (q[j].op == 2) tr[now ^ 1].Mul(q[j].l, q[j].r, q[j].x);
now ^= 1;
}
}
return 0;
}