D e s c r i p t i o n Description Description
如题,已知一个数列,有下列三种操作:
操作1:将某区间每一个数乘上
x
x
x
操作2:将某区间每一个数加上
x
x
x
操作3:查询某区间每一个数的和
S o l u t i o n Solution Solution
线段树模板
和【模板】线段树 1差不多
只不过操作2要处理一下
有两个下传标志
a
d
d
,
m
u
l
add,\ mul
add, mul
区间加
对于区间加,每个就直接加就好了,也就是
:
:
:
a
[
n
o
w
]
.
a
d
d
=
(
a
[
n
o
w
]
.
a
d
d
+
k
)
m
o
d
p
a[now].add\ =\ (a[now].add\ +\ k)\ mod\ p
a[now].add = (a[now].add + k) mod p
a
[
n
o
w
]
.
s
u
m
=
(
a
[
n
o
w
]
.
s
u
m
+
k
×
(
a
[
n
o
w
]
.
r
−
a
[
n
o
w
]
.
l
+
1
)
)
m
o
d
p
a[now].sum\ =\ (a[now].sum\ +\ k\ \times\ (a[now].r\ -\ a[now].l\ +\ 1))\ mod\ p
a[now].sum = (a[now].sum + k × (a[now].r − a[now].l + 1)) mod p
区间乘
根据乘法分配律,
a
d
d
,
s
u
m
,
m
u
l
add,\ sum,\ mul
add, sum, mul同时乘
k
k
k
a
[
n
o
w
]
.
s
u
m
=
(
a
[
n
o
w
]
.
s
u
m
×
k
)
m
o
d
p
a[now].sum = (a[now].sum \times k)\ mod\ p
a[now].sum=(a[now].sum×k) mod p
a
[
n
o
w
]
.
m
u
l
=
(
a
[
n
o
w
]
.
m
u
l
×
k
)
m
o
d
p
a[now].mul = (a[now].mul \times k)\ mod\ p
a[now].mul=(a[now].mul×k) mod p
a
[
n
o
w
]
.
a
d
d
=
(
a
[
n
o
w
]
.
a
d
d
×
k
)
m
o
d
p
a[now].add = (a[now].add \times k)\ mod\ p
a[now].add=(a[now].add×k) mod p
下传
s
u
m
sum
sum下传就是子孩子先乘一个
m
u
l
mul
mul然后加上
a
d
d
,
add,
add,因为
a
d
d
add
add已经乘过所以直接加就好了
a
[
s
o
n
]
.
s
u
m
=
(
a
[
s
o
n
]
.
s
u
m
×
a
[
n
o
w
]
.
m
u
l
+
a
[
n
o
w
]
.
a
d
d
×
(
a
[
s
o
n
]
.
r
−
a
[
s
o
n
]
.
l
+
1
)
)
m
o
d
p
a[son].sum = (a[son].sum \times a[now].mul + a[now].add\times(a[son].r - a[son].l+1))\ mod\ p
a[son].sum=(a[son].sum×a[now].mul+a[now].add×(a[son].r−a[son].l+1)) mod p
m
u
l
mul
mul下传就直接乘
a
[
s
o
n
]
.
m
u
l
=
(
a
[
s
o
n
]
.
m
u
l
×
a
[
n
o
w
]
.
m
u
l
)
m
o
d
p
a[son].mul = (a[son].mul \times a[now].mul)\ mod\ p
a[son].mul=(a[son].mul×a[now].mul) mod p
a
d
d
add
add下传和
s
u
m
sum
sum相似
a
[
s
o
n
]
.
a
d
d
=
(
a
[
s
o
n
]
.
a
d
d
×
a
[
n
o
w
]
.
m
u
l
+
a
[
n
o
w
]
.
a
d
d
)
m
o
d
p
a[son].add = (a[son].add \times a[now].mul + a[now].add)\ mod\ p
a[son].add=(a[son].add×a[now].mul+a[now].add) mod p
A c c e p t e d c o d e Accepted\ code Accepted code
#include<cstdio>
#include<iostream>
#define int long long
#define ls (now << 1)
#define rs (now << 1 | 1)
#define mid (a[now].l + a[now].r >> 1)
using namespace std;
const int N = 1e5 + 5;
struct Tree {
int l, r, add, sum, mul;
}a[N<<2];
int n, q, k, mod;
inline void read(int &f) {
f = 0; char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) f = f * 10 + c - 48, c = getchar();
return;
}
void build(int now, int l, int r) {
a[now] = (Tree){l, r, 0, 0, 1};
if (l == r) {
read(a[now].sum);
a[now].sum %= mod;
return;
}
build(ls, l, mid);
build(rs, mid + 1, r);
a[now].sum = (a[ls].sum + a[rs].sum) % mod;
}
void pd(int now) {
a[ls].sum = (a[ls].sum * a[now].mul + a[now].add * (a[ls].r - a[ls].l + 1)) % mod;
a[rs].sum = (a[rs].sum * a[now].mul + a[now].add * (a[rs].r - a[rs].l + 1)) % mod;
(a[ls].mul *= a[now].mul) %= mod;
(a[rs].mul *= a[now].mul) %= mod;
a[ls].add = (a[ls].add * a[now].mul + a[now].add) % mod;
a[rs].add = (a[rs].add * a[now].mul + a[now].add) % mod;
a[now].mul = 1, a[now].add = 0;
}
void mul(int now, int l, int r, int w) {
if (a[now].l >= l && a[now].r <= r) {
(a[now].sum *= w) %= mod;
(a[now].mul *= w) %= mod;
(a[now].add *= w) %= mod;
return;
}
pd(now);
if (l <= mid) mul(ls, l, r, w);
if (r > mid) mul(rs, l, r, w);
a[now].sum = (a[ls].sum + a[rs].sum) % mod;
return;
}
void add(int now, int l, int r, int w) {
if (a[now].l >= l && a[now].r <= r) {
(a[now].add += w) %= mod;
(a[now].sum += w * (a[now].r - a[now].l + 1)) %= mod;
return;
}
pd(now);
if (l <= mid) add(ls, l, r, w);
if (r > mid) add(rs, l, r, w);
a[now].sum = (a[ls].sum + a[rs].sum) % mod;
return;
}
int ask(int now, int l, int r) {
if (a[now].l >= l && a[now].r <= r)
return a[now].sum;
pd(now);
int sum = 0;
if (l <= mid) (sum += ask(ls, l, r)) %= mod;
if (r > mid) (sum += ask(rs, l, r)) %= mod;
return sum;
}
signed main() {
read(n), read(q), read(mod);
build(1, 1, n);
while (q--) {
int flag, cl, cr, k;
read(flag), read(cl), read(cr);
if (flag == 1) read(k), mul(1, cl, cr, k);
else if (flag == 2) read(k), add(1, cl, cr, k);
else printf("%lld\n", ask(1, cl, cr));
}
}