区间加线段树
struct tnode
{
LL val, add;
tnode* lson,* rson;
tnode(LL num = 0)
{
val = num; add = 0; lson = rson = NULL;
}
~tnode()
{
if (lson) delete lson;
if (rson) delete rson;
}
void maintain()
{
val = lson->val + rson->val;
}
void pushdown(int l, int r)
{
int mid = (l + r) >> 1;
lson->val += LL(mid - l + 1) * add; rson->val += LL(r - mid) * add;
lson->add += add; rson->add += add;
add = 0;
}
};
tnode* tre[N];
tnode* newt(int l, int r)
{
if (l == r) return new tnode(a[l]);
tnode* ret = new tnode();
int mid = (l + r) >> 1;
ret->lson = newt(l, mid);
ret->rson = newt(mid + 1, r);
ret->maintain();
return ret;
}
void addt(tnode* cur, int l, int r, int ql, int qr, LL val)
{
if (ql <= l && r <= qr){
cur->val += LL(r - l + 1) * val; cur->add += val;
return ;
}
int mid = (l + r) >> 1;
cur->pushdown(l, r);
if (ql <= mid) addt(cur->lson, l, mid, ql, qr, val);
if (qr > mid) addt(cur->rson, mid + 1, r, ql, qr, val);
cur->maintain();
}
LL queryt(tnode* cur, int l, int r, int ql, int qr)
{
if (ql <= l && r <= qr) return cur->val;
int mid = (l + r) >> 1; LL ret = 0;
cur->pushdown(l, r);
if (ql <= mid) ret += queryt(cur->lson, l, mid, ql, qr);
if (qr > mid) ret += queryt(cur->rson, mid + 1, r, ql, qr);
return ret;
}
区间加乘线段树
struct tnode
{
LL val, add, mul;
tnode* lson,* rson;
tnode(LL num = 0)
{
val = num % P, add = 0, mul = 1, lson = rson = NULL;
}
~tnode()
{
if (lson) delete lson;
if (rson) delete rson;
}
void maintain()
{
val = lson->val + rson->val;
if (val >= P) val -= P;
}
void pushdown(int l, int r)
{
int mid = (l + r) >> 1;
(lson->val *= mul) %= P; (rson->val *= mul) %= P;
(lson->val += LL(mid - l + 1) * add) %= P; (rson->val += LL(r - mid) * add) %= P;
(lson->mul *= mul) %= P; (rson->mul *= mul) %= P;
(lson->add *= mul) %= P; (rson->add *= mul) %= P;
lson->add += add; if (lson->add >= P) lson->add -= P;
rson->add += add; if (rson->add >= P) rson->add -= P;
mul = 1, add = 0;
}
};
tnode* tre[N];
tnode* newt(int l, int r){
if (l == r) return new tnode(a[l]);
tnode* ret = new tnode();
int mid = (l + r) >> 1;
ret->lson = newt(l, mid); ret->rson = newt(mid + 1, r);
ret->maintain();
return ret;
}
void addt(tnode* cur, int l, int r, int ql, int qr, LL val)
{
if (ql <= l && r <= qr){
(cur->val += LL(r - l + 1) * val) %= P; (cur->add += val) %= P;
return ;
}
int mid = (l + r) >> 1;
cur->pushdown(l, r);
if (ql <= mid) addt(cur->lson, l, mid, ql, qr, val);
if (qr > mid) addt(cur->rson, mid + 1, r, ql, qr, val);
cur->maintain();
}
void mult(tnode* cur, int l, int r, int ql, int qr, LL val)
{
if (ql <= l && r <= qr){
(cur->val *= val) %= P; (cur->mul *= val) %= P; (cur->add *= val) %= P;
return ;
}
int mid = (l + r) >> 1;
cur->pushdown(l, r);
if (ql <= mid) mult(cur->lson, l, mid, ql, qr, val);
if (qr > mid) mult(cur->rson, mid + 1, r, ql, qr, val);
cur->maintain();
}
LL queryt(tnode* cur, int l, int r, int ql, int qr)
{
if (ql <= l && r <= qr) return cur->val;
int mid = (l + r) >> 1; LL ret = 0;
cur->pushdown(l, r);
if (ql <= mid) ret += queryt(cur->lson, l, mid, ql, qr); if (ret >= P) ret -= P;
if (qr > mid) ret += queryt(cur->rson, mid + 1, r, ql, qr); if (ret >= P) ret -= P;
return ret;
}