线段树模板

void pushdown(int l, int r, int rt)
{
    if (lazy[rt])
    {
        sum[rt << 1] += l * lazy[rt];
        sum[(rt << 1) + 1] += r * lazy[rt];
        lazy[rt << 1] += lazy[rt];
        lazy[(rt << 1) + 1] += lazy[rt];
        lazy[rt] = 0;
    }
}
void build(int l, int r, int rt)
{
    if (l == r)
    {
        sum[rt] = tmp[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, rt << 1);
    build(mid + 1, r, (rt << 1) + 1);
    sum[rt] = sum[rt << 1] + sum[(rt << 1) + 1];
}
void update(int l, int r, int rt, int l1, int r1, int v)
{
    if (l1 <= l && r <= r1)
    {
        sum[rt] += v * (r - l + 1);
        lazy[rt] += v;
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(mid - l + 1, r - mid, rt);
    if (l1 <= mid)
        update(l, mid, rt << 1, l1, r1, v);
    if (r1 > mid)
        update(mid + 1, r, (rt << 1) + 1, l1, r1, v);
    sum[rt] = sum[rt << 1] + sum[(rt << 1) + 1];
}
int query(int l, int r, int rt, int l1, int r1)
{
    if (l1 <= l && r <= r1)
        return (ll)sum[rt];
    int mid = (l + r) >> 1;
    int ret = 0;
    pushdown(mid - l + 1, r - mid, rt);
    if (l1 <= mid)
        ret += query(l, mid, rt << 1, l1, r1);
    if (r1 > mid)
        ret += query(mid + 1, r, (rt << 1) + 1, l1, r1);
    sum[rt] = sum[rt << 1] + sum[(rt << 1) + 1];
    return ret;
}

线段树区间加法,区间乘法,区间查询

#include <bits/stdc++.h>

#define ll long long
#define ull unsigned long long
#define met(a,x) memset(a,x,sizeof(a))
#define inf 0x3f3f3f3f
#define mp make_pair;

using namespace std;
const int maxn = 100000 + 10;
const int mod=1e9+7;
ll A[maxn << 1], Sum[maxn << 3], Add[maxn << 3], Mul[maxn << 3];
ll n, s, p;

void PushUp(ll rt) { Sum[rt] = (Sum[rt << 1] + Sum[rt << 1 | 1]) % p; }//上推函数
void PushDown(ll rt, ll m)//下推函数,注意乘法优先级比加法高
{
    if (Add[rt] || Mul[rt] != 1) {
        Sum[rt << 1] = (Sum[rt << 1] * Mul[rt] + Add[rt] * (m - (m >> 1))) % p;
        Sum[rt << 1 | 1] = (Sum[rt << 1 | 1] * Mul[rt] + Add[rt] * (m >> 1)) % p;
        Add[rt << 1] = (Add[rt << 1] * Mul[rt] + Add[rt]) % p;
        Add[rt << 1 | 1] = (Add[rt << 1 | 1] * Mul[rt] + Add[rt]) % p;
        Mul[rt << 1] = (Mul[rt << 1] * Mul[rt]) % p;
        Mul[rt << 1 | 1] = (Mul[rt << 1 | 1] * Mul[rt]) % p;
        Add[rt] = 0;
        Mul[rt] = 1;
    }
}

void Build(ll l, ll r, ll rt)//建树
{
    Add[rt] = 0;
    Mul[rt] = 1;
    if (l == r) {
        Sum[rt] = A[l] % p;
        return;
    }
    ll m = (l + r) >> 1;
    Build(l, m, rt << 1);
    Build(m + 1, r, rt << 1 | 1);
    PushUp(rt);
}

void Update_mul(ll L, ll R, ll C, ll l, ll r, ll rt)//区间乘法运算
{
    PushDown(rt, (r - l + 1));
    if (L <= l && r <= R) {
        Sum[rt] = Sum[rt] * C;
        Sum[rt] = Sum[rt] % p;
        Mul[rt] = Mul[rt] * C;
        Mul[rt] = Mul[rt] % p;
        return;
    }
    ll m = (l + r) >> 1;
    if (L <= m) Update_mul(L, R, C, l, m, rt << 1);
    if (R > m) Update_mul(L, R, C, m + 1, r, rt << 1 | 1);
    PushUp(rt);
}

void Update_plu(ll L, ll R, ll C, ll l, ll r, ll rt)//区间加法运算
{
    PushDown(rt, r - l + 1);
    if (L <= l && r <= R) {
        Sum[rt] = (Sum[rt] + (r - l + 1) * C) % p;
        Add[rt] = (Add[rt] + C) % p;
        return;
    }
    ll m = (l + r) >> 1;
    if (L <= m) Update_plu(L, R, C, l, m, rt << 1);
    if (R > m) Update_plu(L, R, C, m + 1, r, rt << 1 | 1);
    PushUp(rt);
}

ll Query(ll L, ll R, ll l, ll r, ll rt)//区间查询
{
    PushDown(rt, r - l + 1);
    if (L <= l && r <= R) {
        return Sum[rt];
    }
    ll m = (l + r) >> 1, Ans = 0;
    if (L <= m) Ans = (Ans + Query(L, R, l, m, rt << 1)) % p;
    if (R > m) Ans = (Ans + Query(L, R, m + 1, r, rt << 1 | 1)) % p;
    return Ans;
}

int main()//各种操作
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    scanf("%lld%lld", &n, &p);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &A[i]);
    Build(1, n, 1);
    scanf("%lld", &s);
    for (int i = 1; i <= s; i++) {
        ll t, x, y, k;
        scanf("%lld%lld%lld", &t, &x, &y);
        if (t == 1) {
            scanf("%lld", &k);
            Update_mul(x, y, k, 1, n, 1);
        }
        if (t == 2) {
            scanf("%lld", &k);
            Update_plu(x, y, k, 1, n, 1);
        }
        if (t == 3) {
            printf("%lld
", Query(x, y, 1, n, 1));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/nublity/p/10456611.html