データ構造 - セグメントツリー

データ構造 - セグメントツリー

テンプレート1トピックのリンク:https://www.luogu.org/problem/P3372

インターバル、インターバルクエリコードを変更します。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 100010;

int n, m;
ll num[N];

struct Segment_tree {
    ll tree[N << 2];
    ll lazy[N << 2];
    
    #define lson pos << 1
    #define rson pos << 1 | 1
    
    void pushup(int pos) {
        tree[pos] = tree[lson] + tree[rson];
    }
    
    void pushdown(int pos, int l, int r) {
        if (lazy[pos]) {
            int mid = (l + r) >> 1;
            lazy[lson] += lazy[pos];
            lazy[rson] += lazy[pos];
            tree[lson] += 1ll * (mid - l + 1) * lazy[pos];
            tree[rson] += 1ll * (r - mid) * lazy[pos];
            lazy[pos] = 0;
        }
    }
    
    void build(int pos, int l, int r) {
        if (l == r) {
            tree[pos] = num[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(lson, l, mid);
        build(rson, mid + 1, r);
        pushup(pos);
    }
    
    void update(int pos, int l, int r, int x, int y, ll v) {
        if (x <= l && r <= y) {
            tree[pos] += 1ll * (r - l + 1) * v;
            lazy[pos] += v;
            return ;
        }
        int mid = (l + r) >> 1;
        pushdown(pos, l, r);
        if (x <= mid) {
            update(lson, l, mid, x, y, v);
        }
        if (y > mid) {
            update(rson, mid + 1, r, x, y, v);
        }
        pushup(pos);
    }
    
    ll query(int pos, int l, int r, int x, int y) {
        if (x <= l && r <= y) {
            return tree[pos];
        }
        int mid = (l + r) >> 1;
        pushdown(pos, l, r);
        ll ret = 0;
        if (x <= mid) {
            ret += query(lson, l, mid, x, y);
        }
        if (y > mid) {
            ret += query(rson, mid + 1, r, x, y);
        }
        return ret;
    }
    #undef lson
    #undef rson
} sgt;

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ ) {
        scanf("%lld", &num[i]);
    }
    sgt.build(1, 1, n);
    for (int i = 1; i <= m; i ++ ) {
        int opt, x, y;
        ll k;
        scanf("%d", &opt);
        if (opt == 1) {
            scanf("%d%d%lld", &x, &y, &k);
            sgt.update(1, 1, n, x, y, k);
        }
        else {
            scanf("%d%d", &x, &y);
            ll ans = sgt.query(1, 1, n, x, y);
            printf("%lld\n", ans);
        }   
    }
    return 0;
}

デュアル修正(乗算間隔、間隔プラス)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int n, m, mod;

int a[N];

struct Segment_tree {
    
    #define lson pos << 1
    #define rson pos << 1 | 1

    struct Tree {
        int mul, add, num; 
        Tree() {
            mul = add = num = 0;
        }
    } tr[N << 2];
    
    void pushup(int pos) {
        tr[pos].num = (tr[lson].num + tr[rson].num) % mod;
    }
    
    void pushdown(int pos, int l, int r) {
        int mid = (l + r) >> 1;
        tr[lson].num = (1ll * tr[lson].num * tr[pos].mul + 1ll * tr[pos].add * (mid - l + 1)) % mod;
        tr[rson].num = (1ll * tr[rson].num * tr[pos].mul + 1ll * tr[pos].add * (r - mid)) % mod;
        tr[lson].mul = (1ll * tr[lson].mul * tr[pos].mul) % mod;
        tr[rson].mul = (1ll * tr[rson].mul * tr[pos].mul) % mod;
        tr[lson].add = (1ll * tr[lson].add * tr[pos].mul + tr[pos].add) % mod;
        tr[rson].add = (1ll * tr[rson].add * tr[pos].mul + tr[pos].add) % mod;
        tr[pos].mul = 1;
        tr[pos].add = 0;
    }
    
    void build(int pos, int l, int r) {
        tr[pos].mul = 1;
        tr[pos].add = 0;
        if (l == r) {
            tr[pos].num = a[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(lson, l, mid);
        build(rson, mid + 1, r);
        pushup(pos);
    }
    
    void update_add(int pos, int l, int r, int x, int y, int val) {
        if (x <= l && r <= y) {
            tr[pos].add = (1ll * tr[pos].add + val) % mod;
            tr[pos].num = (1ll * tr[pos].num + 1ll * val * (r - l + 1)) % mod;
            return ;
        }
        int mid = (l + r) >> 1;
        pushdown(pos, l, r);
        if (x <= mid) {
            update_add(lson, l, mid, x, y, val);
        }
        if (y > mid) {
            update_add(rson, mid + 1, r, x, y, val);
        }
        pushup(pos);
    }
    
    void update_mul(int pos, int l, int r, int x, int y, int val) {
        if (x <= l && r <= y) {
            tr[pos].mul = (1ll * tr[pos].mul * val) % mod;
            tr[pos].add = (1ll * tr[pos].add * val) % mod;
            tr[pos].num = (1ll * tr[pos].num * val) % mod;
            return ;
        }
        int mid = (l + r) >> 1;
        pushdown(pos, l, r);
        if (x <= mid) {
            update_mul(lson, l, mid, x, y, val);
        }
        if (y > mid) {
            update_mul(rson, mid + 1, r, x, y, val);
        }
        pushup(pos);
    }
    
    int query(int pos, int l, int r, int x, int y) {
        if (x <= l && r <= y) {
            return tr[pos].num;
        }
        int mid = (l + r) >> 1;
        pushdown(pos, l, r);
        int ret = 0;
        if (x <= mid) {
            ret = (ret + 1ll * query(lson, l, mid, x, y)) % mod;
        }
        if (y > mid) {
            ret = (ret + 1ll * query(rson, mid + 1, r, x, y)) % mod;
        }
        return ret;
    }
    
    #undef lson
    #undef rson
    
} sgt;



int main() {
    scanf("%d%d%d", &n, &m, &mod);
    for (int i = 1; i <= n; i ++ ) {
        scanf("%d", &a[i]);
    }
    sgt.build(1, 1, n);
    for (int i = 1; i <= m; i ++ ) {
        int opt, x, y, k;
        scanf("%d%d%d", &opt, &x, &y);
        if (opt == 1) {
            scanf("%d", &k);
            sgt.update_mul(1, 1, n, x, y, k);
        }
        else if (opt == 2) {
            scanf("%d", &k);
            sgt.update_add(1, 1, n, x, y, k);
        }
        else {
            int ans = sgt.query(1, 1, n, x, y);
            printf("%d\n", ans);
        }
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/littleseven777/p/11867225.html