# 浅谈线段树中加与乘标记的下放

• 第一种：先加再乘

(也就是提出$mul*\_mul$这一项)得

$(val+add+\frac{\_add}{mul})*mul*\_mul$

• 第二种：先乘再加

$val*mul*\_mul+add*\_mul+\_add$

#include<cstdio>
#include<cmath>
#include<algorithm>
#define ls k<<1
#define rs k<<1|1
#define int long long
using namespace std;
const int MAXN = 1e6 + 10;
char c = getchar(); int x = 0, f = 1;
while (c < '0' || c > '9') {if (c == '-')f = -1; c = getchar();}
while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return x * f;
}
int N, M, mod;
struct node {
int mul, add, sum, l, r, siz;
} T[MAXN];
void update(int k) {
T[k].sum = (T[ls].sum % mod + T[rs].sum % mod) % mod;
}
void ps(int x, int f) {
T[x].mul = (T[x].mul % mod * T[f].mul % mod) % mod;
T[x].sum = (T[x].sum % mod * T[f].mul % mod) % mod;
T[x].sum = (T[x].sum + T[f].add % mod * T[x].siz) % mod;
}
void pushdown(int k) {
if (T[k].add == 0 && T[k].mul == 1) return ;
ps(ls, k);
ps(rs, k);
T[k].mul = 1;
}
void Build(int k, int ll, int rr) {
T[k].l = ll; T[k].r = rr; T[k].siz = rr - ll + 1; T[k].mul = 1;
if (ll == rr) {
return ;
}
int mid = ll + rr >> 1;
Build(ls, ll, mid);
Build(rs, mid + 1, rr);
update(k);
}
void IntervalMul(int k, int ll, int rr, int val) {
if (ll <= T[k].l && T[k].r <= rr) {
T[k].sum = (T[k].sum * val) % mod;
T[k].mul = (T[k].mul * val) % mod;
return ;
}
pushdown(k);
int mid = T[k].l + T[k].r >> 1;
if (ll <= mid) IntervalMul(ls, ll, rr, val);
if (rr > mid)  IntervalMul(rs, ll, rr, val);
update(k);
}
void IntervalAdd(int k, int ll, int rr, int val) {
if (ll <= T[k].l && T[k].r <= rr) {
T[k].sum = (T[k].sum + T[k].siz * val) % mod;
return ;
}
pushdown(k);
int mid = T[k].l + T[k].r >> 1;
if (ll <= mid) IntervalAdd(ls, ll, rr, val);
if (rr > mid)  IntervalAdd(rs, ll, rr, val);
update(k);
}
int IntervalSum(int k, int ll, int rr) {
int ans = 0;
if (ll <= T[k].l && T[k].r <= rr) {
ans = (ans + T[k].sum) % mod;
return ans;
}
pushdown(k);
int mid = T[k].l + T[k].r >> 1;
if (ll <= mid) ans = (ans + IntervalSum(ls, ll, rr)) % mod;
if (rr > mid)  ans = (ans + IntervalSum(rs, ll, rr)) % mod;
return ans % mod;
}
main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
#endif
Build(1, 1, N);
while (M--) {
if (opt == 1) {
IntervalMul(1, l, r, val);
} else if (opt == 2) {
}