玄关
查看原帖
玄关
1046223
a_blue_fool楼主2024/6/5 16:54
#include <iostream>
#include <cstdio>
#include <vector>

using namespace std;

const long long MAXN = 100005;

struct Node {
    long long sum;
    long long lazy_mul;
    long long lazy_add;
};

Node tree[4 * MAXN];
long long nums[MAXN];
long long m , n, q;

void build(long long node, long long l, long long r) {
    if (l == r) {
        tree[node].sum = nums[l] % m;
        tree[node].lazy_mul = 1;
        tree[node].lazy_add = 0;
    } else {
        long long mid = (l + r) / 2;
        build(2 * node, l, mid);
        build(2 * node + 1, mid + 1, r);
        tree[node].sum = (tree[2 * node].sum + tree[2 * node + 1].sum) % m;
        tree[node].lazy_mul = 1;
        tree[node].lazy_add = 0;
    }
}

void update(long long node, long long l, long long r, long long left, long long right, long long op, long long val) {

    if (l > right || r < left) { //是合理区间
        return;
    }

    tree[node].sum = (tree[node].sum * tree[node].lazy_mul + (r - l + 1) * tree[node].lazy_add) % m; //更新当前
    if (l != r) { //不是叶子节点
        tree[2 * node].lazy_mul = (tree[2 * node].lazy_mul * tree[node].lazy_mul) % m;
        tree[2 * node].lazy_add = (tree[2 * node].lazy_add * tree[node].lazy_mul + tree[node].lazy_add) % m;

        tree[2 * node + 1].lazy_mul = (tree[2 * node + 1].lazy_mul * tree[node].lazy_mul) % m;
        tree[2 * node + 1].lazy_add = (tree[2 * node + 1].lazy_add * tree[node].lazy_mul + tree[node].lazy_add) % m;
    }
    tree[node].lazy_mul = 1; //懒惰标记复原
    tree[node].lazy_add = 0;

    if (l >= left && r <= right) { //完全包含
        if (op == 1) { //乘法
            tree[node].sum = (tree[node].sum * val) % m;
            if (l != r) {
                tree[2 * node].lazy_mul = (tree[2 * node].lazy_mul * val) % m;
                tree[2 * node + 1].lazy_mul = (tree[2 * node + 1].lazy_mul * val) % m;
            }
        } else { //加法
            tree[node].sum = (tree[node].sum + (r - l + 1) * val) % m;
            if (l != r) {
                tree[2 * node].lazy_add = (tree[2 * node].lazy_add + val) % m;
                tree[2 * node + 1].lazy_add = (tree[2 * node + 1].lazy_add + val) % m;
            }
        }
        return;
    }
    long long mid = (l + r) / 2; //向下继续更新
    update(2 * node, l, mid, left, right, op, val);
    update(2 * node + 1, mid + 1, r, left, right, op, val);
    tree[node].sum = (tree[2 * node].sum + tree[2 * node + 1].sum) % m;
}

long long query(long long node, long long l, long long r, long long left, long long right) {
    if (l > right || r < left) { //非法区间
        return 0;
    }

    tree[node].sum = (tree[node].sum * tree[node].lazy_mul + (r - l + 1) * tree[node].lazy_add) % m; //把懒惰标记加入答案
    if (l != r) { //不是叶子节点,下放懒惰标记
        tree[2 * node].lazy_mul = (tree[2 * node].lazy_mul * tree[node].lazy_mul) % m;
        tree[2 * node].lazy_add = (tree[2 * node].lazy_add * tree[node].lazy_mul + tree[node].lazy_add) % m;

        tree[2 * node + 1].lazy_mul = (tree[2 * node + 1].lazy_mul * tree[node].lazy_mul) % m;
        tree[2 * node + 1].lazy_add = (tree[2 * node + 1].lazy_add * tree[node].lazy_mul + tree[node].lazy_add) % m;
    }
    tree[node].lazy_mul = 1; //懒惰标记复原
    tree[node].lazy_add = 0;

    if (l >= left && r <= right) { //完全包含
        return tree[node].sum;
    }

    long long mid = (l + r) / 2;
    long long left_sum = query(2 * node, l, mid, left, right);
    long long right_sum = query(2 * node + 1, mid + 1, r, left, right);
    return (left_sum + right_sum) % m;
}

signed main() {
    cin >> n >> q >> m;

    for (long long i = 1; i <= n; i++) {
        cin >> nums[i];
    }

    build(1, 1, n);

    for (long long i = 0; i < q; i++) {
        long long op, x, y, k;
        cin >> op >> x >> y;
        if (op == 1 || op == 2) {
            cin >> k;
            update(1, 1, n, x, y, op, k);
        } else if (op == 3) {
            cout << query(1, 1, n, x, y) << endl;
        }
    }

    return 0;
}

2024/6/5 16:54
加载中...