Loading

线段树模板3.0 区间乘

线段树模板3.0 区间乘

注意lazy标记应用

先乘后加

int MOD;

struct Tree {
    ll l, r;
    ll sum;
    ll mul, add;
};

Tree node[maxn << 2];
int a[maxn];

void push_up(int i) {
    node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum;
    node[i].sum %= MOD;
}

void build(int i, int l, int r) {
    node[i].l = l;
    node[i].r = r;
    node[i].mul = 1;
    if (l == r) {
        node[i].sum = a[l] % MOD;
        return;
    }
    int mid = l + r >> 1;
    build(i << 1, l, mid);
    build(i << 1 | 1, mid + 1, r);
    push_up(i);
}

void push_down(int i) {
    node[i << 1].sum = (ll)node[i].mul * node[i << 1].sum  % MOD + ((ll)(node[i << 1].r - node[i << 1].l + 1) * node[i].add % MOD) % MOD;
    node[i << 1].sum %= MOD;
    node[i << 1 | 1].sum = (ll)node[i].mul * node[i << 1 | 1].sum % MOD + ((ll)node[i].add * (node[i << 1 | 1].r - node[i << 1 | 1].l + 1) % MOD) % MOD;
    node[i << 1 | 1].sum %= MOD;
    
    node[i << 1].mul = (ll)node[i << 1].mul * node[i].mul % MOD;
    node[i << 1 | 1].mul = (ll)node[i << 1 | 1].mul * node[i].mul % MOD;
   
    node[i << 1].add = (ll)node[i << 1].add * node[i].mul % MOD + node[i].add;
    node[i << 1].add %= MOD;
    node[i << 1 | 1].add = (ll)node[i << 1 | 1].add * node[i].mul % MOD + node[i].add;
    node[i << 1 | 1].add %= MOD;
    
    node[i].mul = 1;
    node[i].add = 0;
}

void update1(int i, int l, int r, ll val) {
    if (node[i].l > r || node[i].r < l) return;
    if (node[i].l >= l && node[i].r <= r) {
        node[i].add += val;
        node[i].add %= MOD;
        node[i].sum += val * (node[i].r - node[i].l + 1) % MOD;
        node[i].sum %= MOD;
        return;
    }
    push_down(i);
    int mid = node[i].l + node[i].r >> 1;
    if(l <= mid) update1(i << 1, l, r, val);
    if(r > mid) update1(i << 1 | 1, l, r, val);
    push_up(i);
}

void update2(int i, int l, int r, ll val) {
    if (node[i].l > r || node[i].r < l) return;
    if (node[i].l >= l && node[i].r <= r) {
        node[i].add = (ll)node[i].add * val % MOD;    //注意这里add也要乘上val
        node[i].mul = (ll)node[i].mul * val % MOD;
        node[i].sum = (ll)node[i].sum * val % MOD;
        return;
    }
    push_down(i);
    update2(i << 1, l, r, val);
    update2(i << 1 | 1, l, r, val);
    push_up(i);
}

ll query(int i, int l, int r) {
    if (node[i].l > r || node[i].r < l) return 0;
    if (node[i].l >= l && node[i].r <= r)  return node[i].sum;
    push_down(i);
    return (query(i << 1, l, r) + query(i << 1 | 1, l, r)) % MOD;
}

int main() {
    int n = readint();
    int m = readint();
    MOD = readint();
    for (int i = 1; i <= n; i++)
        a[i] = readint();
    build(1, 1, n);
    for (int i = 1; i <= m; i++) {
        int op = readint();
        if (op == 1) {
            int L = readint();
            int R = readint();
            int V = readint();
            update2(1, L, R, V);
        }
        else if (op == 2) {
            int L = readint();
            int R = readint();
            int V = readint();
            update1(1, L, R, V);
        }
        else {
            int L = readint();
            int R = readint();
            Put(query(1, L, R));
            puts("");
        }
    }
}
posted @ 2020-10-18 12:42  MQFLLY  阅读(84)  评论(0编辑  收藏  举报