数据结构 - 线段树
数据结构 - 线段树
模板1 题目链接:https://www.luogu.org/problem/P3372
区间修改、区间查询 代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
int n, m;
ll num[N];
struct Segment_tree {
ll tree[N << 2];
ll lazy[N << 2];
#define lson pos << 1
#define rson pos << 1 | 1
void pushup(int pos) {
tree[pos] = tree[lson] + tree[rson];
}
void pushdown(int pos, int l, int r) {
if (lazy[pos]) {
int mid = (l + r) >> 1;
lazy[lson] += lazy[pos];
lazy[rson] += lazy[pos];
tree[lson] += 1ll * (mid - l + 1) * lazy[pos];
tree[rson] += 1ll * (r - mid) * lazy[pos];
lazy[pos] = 0;
}
}
void build(int pos, int l, int r) {
if (l == r) {
tree[pos] = num[l];
return ;
}
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
pushup(pos);
}
void update(int pos, int l, int r, int x, int y, ll v) {
if (x <= l && r <= y) {
tree[pos] += 1ll * (r - l + 1) * v;
lazy[pos] += v;
return ;
}
int mid = (l + r) >> 1;
pushdown(pos, l, r);
if (x <= mid) {
update(lson, l, mid, x, y, v);
}
if (y > mid) {
update(rson, mid + 1, r, x, y, v);
}
pushup(pos);
}
ll query(int pos, int l, int r, int x, int y) {
if (x <= l && r <= y) {
return tree[pos];
}
int mid = (l + r) >> 1;
pushdown(pos, l, r);
ll ret = 0;
if (x <= mid) {
ret += query(lson, l, mid, x, y);
}
if (y > mid) {
ret += query(rson, mid + 1, r, x, y);
}
return ret;
}
#undef lson
#undef rson
} sgt;
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) {
scanf("%lld", &num[i]);
}
sgt.build(1, 1, n);
for (int i = 1; i <= m; i ++ ) {
int opt, x, y;
ll k;
scanf("%d", &opt);
if (opt == 1) {
scanf("%d%d%lld", &x, &y, &k);
sgt.update(1, 1, n, x, y, k);
}
else {
scanf("%d%d", &x, &y);
ll ans = sgt.query(1, 1, n, x, y);
printf("%lld\n", ans);
}
}
return 0;
}
双修改(区间乘、区间加)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, mod;
int a[N];
struct Segment_tree {
#define lson pos << 1
#define rson pos << 1 | 1
struct Tree {
int mul, add, num;
Tree() {
mul = add = num = 0;
}
} tr[N << 2];
void pushup(int pos) {
tr[pos].num = (tr[lson].num + tr[rson].num) % mod;
}
void pushdown(int pos, int l, int r) {
int mid = (l + r) >> 1;
tr[lson].num = (1ll * tr[lson].num * tr[pos].mul + 1ll * tr[pos].add * (mid - l + 1)) % mod;
tr[rson].num = (1ll * tr[rson].num * tr[pos].mul + 1ll * tr[pos].add * (r - mid)) % mod;
tr[lson].mul = (1ll * tr[lson].mul * tr[pos].mul) % mod;
tr[rson].mul = (1ll * tr[rson].mul * tr[pos].mul) % mod;
tr[lson].add = (1ll * tr[lson].add * tr[pos].mul + tr[pos].add) % mod;
tr[rson].add = (1ll * tr[rson].add * tr[pos].mul + tr[pos].add) % mod;
tr[pos].mul = 1;
tr[pos].add = 0;
}
void build(int pos, int l, int r) {
tr[pos].mul = 1;
tr[pos].add = 0;
if (l == r) {
tr[pos].num = a[l];
return ;
}
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
pushup(pos);
}
void update_add(int pos, int l, int r, int x, int y, int val) {
if (x <= l && r <= y) {
tr[pos].add = (1ll * tr[pos].add + val) % mod;
tr[pos].num = (1ll * tr[pos].num + 1ll * val * (r - l + 1)) % mod;
return ;
}
int mid = (l + r) >> 1;
pushdown(pos, l, r);
if (x <= mid) {
update_add(lson, l, mid, x, y, val);
}
if (y > mid) {
update_add(rson, mid + 1, r, x, y, val);
}
pushup(pos);
}
void update_mul(int pos, int l, int r, int x, int y, int val) {
if (x <= l && r <= y) {
tr[pos].mul = (1ll * tr[pos].mul * val) % mod;
tr[pos].add = (1ll * tr[pos].add * val) % mod;
tr[pos].num = (1ll * tr[pos].num * val) % mod;
return ;
}
int mid = (l + r) >> 1;
pushdown(pos, l, r);
if (x <= mid) {
update_mul(lson, l, mid, x, y, val);
}
if (y > mid) {
update_mul(rson, mid + 1, r, x, y, val);
}
pushup(pos);
}
int query(int pos, int l, int r, int x, int y) {
if (x <= l && r <= y) {
return tr[pos].num;
}
int mid = (l + r) >> 1;
pushdown(pos, l, r);
int ret = 0;
if (x <= mid) {
ret = (ret + 1ll * query(lson, l, mid, x, y)) % mod;
}
if (y > mid) {
ret = (ret + 1ll * query(rson, mid + 1, r, x, y)) % mod;
}
return ret;
}
#undef lson
#undef rson
} sgt;
int main() {
scanf("%d%d%d", &n, &m, &mod);
for (int i = 1; i <= n; i ++ ) {
scanf("%d", &a[i]);
}
sgt.build(1, 1, n);
for (int i = 1; i <= m; i ++ ) {
int opt, x, y, k;
scanf("%d%d%d", &opt, &x, &y);
if (opt == 1) {
scanf("%d", &k);
sgt.update_mul(1, 1, n, x, y, k);
}
else if (opt == 2) {
scanf("%d", &k);
sgt.update_add(1, 1, n, x, y, k);
}
else {
int ans = sgt.query(1, 1, n, x, y);
printf("%d\n", ans);
}
}
return 0;
}