【模板】线段树(区间加、区间乘、区间查询)

C++版本:

区间加法、查询区间和线段树

#define lson (o<<1)
#define rson (o<<1|1)
ll sumv[maxn << 2], addv[maxn << 2], a[maxn];
void cover(ll o, ll l, ll r, ll v) {
	sumv[o] += (r - l + 1)*v;
	addv[o] += v;
}
void pushup(ll o) { sumv[o] = sumv[lson] + sumv[rson]; return; }
void pushdown(ll o, ll l, ll r) {
	ll mid = (l + r) >> 1;
	cover(lson, l, mid, addv[o]);
	cover(rson, mid + 1, r, addv[o]);
	addv[o] = 0;
}
void build(ll o, ll l, ll r) {
	addv[o] = 0;
	if (l == r) { sumv[o] = a[l]; return; }
	ll mid = (l + r) >> 1;
	build(lson, l, mid); build(rson, mid + 1, r);
	pushup(o);
}
void optadd(ll o, ll l, ll r, ll ql, ll qr, ll v) {
	if (ql <= l && r <= qr) { cover(o, l, r, v); return; }
	ll mid = (l + r) >> 1;
	if (addv[o] != 0)pushdown(o, l, r);
	if (ql <= mid)optadd(lson, l, mid, ql, qr, v);
	if (mid < qr)optadd(rson, mid + 1, r, ql, qr, v);
	pushup(o);
}
ll querysum(ll o, ll l, ll r, ll ql, ll qr) {
	if (ql <= l && r <= qr) { return sumv[o]; }
	ll mid = (l + r) >> 1, ans = 0;
	if (addv[o] != 0)pushdown(o, l, r);
	if (ql <= mid)ans += querysum(lson, l, mid, ql, qr);
	if (mid < qr)ans += querysum(rson, mid + 1, r, ql, qr);
	pushup(o);
	return ans;
}

区间加法、区间乘法、查询区间和线段树

ll sumv[maxn << 2], addv[maxn << 2], addx[maxn << 2], a[maxn];
void cover(ll o, ll l, ll r, ll v, ll x) {
	sumv[o] = sumv[o] * x%P;
	addx[o] = addx[o] * x%P;
	addv[o] = addv[o] * x%P;
	sumv[o] = (sumv[o] + (r - l + 1)*v) % P;
	addv[o] = (addv[o] + v) % P;
}
void pushup(ll o) {
	sumv[o] = (sumv[lson] + sumv[rson]) % P;
	return;
}
void pushdown(ll o, ll l, ll r) {
	ll mid = (l + r) >> 1;
	cover(lson, l, mid, addv[o] % P, addx[o] % P);
	cover(rson, mid + 1, r, addv[o] % P, addx[o] % P);
	addx[o] = 1; addv[o] = 0;
}
void build(ll o, ll l, ll r) {
	addv[o] = 0, addx[o] = 1;
	if (l == r) { sumv[o] = a[l] % P; return; }
	ll mid = (l + r) >> 1;
	build(lson, l, mid); build(rson, mid + 1, r);
	pushup(o);
}
void optadd(ll o, ll l, ll r, ll ql, ll qr, ll v) {
	if (ql <= l && r <= qr) { cover(o, l, r, v%P, 1); return; }
	ll mid = (l + r) >> 1;
	if (addv[o] != 0 || addx[o] != 1)pushdown(o, l, r);
	if (ql <= mid)optadd(lson, l, mid, ql, qr, v);
	if (mid < qr)optadd(rson, mid + 1, r, ql, qr, v);
	pushup(o);
}
void optaddx(ll o, ll l, ll r, ll ql, ll qr, ll v) {
	if (ql <= l && r <= qr) { cover(o, l, r, 0, v%P); return; }
	ll mid = (l + r) >> 1;
	if (addv[o] != 0 || addx[o] != 1)pushdown(o, l, r);
	if (ql <= mid)optaddx(lson, l, mid, ql, qr, v%P);
	if (mid < qr)optaddx(rson, mid + 1, r, ql, qr, v%P);
	pushup(o);
}
ll querysum(ll o, ll l, ll r, ll ql, ll qr) {
	if (ql <= l && r <= qr) { return sumv[o] % P; }
	ll mid = (l + r) >> 1, ans = 0;
	if (addv[o] != 0 || addx[o] != 1)pushdown(o, l, r);
	if (ql <= mid)ans += querysum(lson, l, mid, ql, qr);
	if (mid < qr)ans += querysum(rson, mid + 1, r, ql, qr);
	return ans % P;
}
posted @ 2020-09-13 19:43  pjhui  阅读(169)  评论(0编辑  收藏  举报