沿用线段树1的思路写的报错机器
查看原帖
沿用线段树1的思路写的报错机器
767779
BD_AZZR_CN楼主2024/8/8 15:04
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
constexpr long long MAXN = 400000;
class opera {
public:
    short operation;// + is 1,* is 2
    long long value;
    opera(void) { ; };
    opera(short O1, long long O2) { operation = O1; value = O2; };
};
class lineTree {
public:
    long long a[MAXN + 1];
    long long d[MAXN + 1];//真值
    queue<opera> b[MAXN + 1];//偷懒标记
    inline long long ls(long long n) {
        return (n << 1);
    }
    inline long long rs(long long n) {
        return ((n << 1) | 1);
    }
    void build(long long l, long long r, long long p) {//左区间,右区间,当前节点编号
        if (l == r) {
            d[p] = a[l];
            return;
        }
        long long mid = (l + r) >> 1;
        build(l, mid, ls(p));
        build(mid + 1, r, rs(p));
        d[p] = d[ls(p)] + d[rs(p)];
    }

    //添加一个操作,并简化
    void A_mark(long long pos, long long _val, int op, long long len) {
        if (len == 0)return;
        if (!b[pos].empty() && b[pos].back().operation == op) {
            if (op == 1) {
                b[pos].back().value += _val;
                d[pos] += (_val) * (len);
            }
            else {  
                b[pos].back().value *= _val;
                d[pos] *= _val;
            }
        }
        else {
            b[pos].push(opera(op, _val));
            if (op == 1)d[pos] += (_val) * (len);
            else d[pos] *= _val;
        }
    }
    //将当前累积的懒惰操作传递给儿子
    void B_mark(long long p, long long l, long long r) {
        long long m = (l + r) / 2;
        opera t;
        while (!b[p].empty()) {
            t = b[p].front();
            b[p].pop();
            A_mark(ls(p), t.value, t.operation, m - l + 1);
            A_mark(rs(p), t.value, t.operation, r - m);
        }
    }
    //传入左区间,右区间,值,左管辖,右管辖,操作符
    void update(long long l, long long r, long long c, long long s, long long t, long long p, int op) {
        if (l <= s && t <= r) {
            A_mark(p, c, op, t - s + 1);
            return;
        }
        long long m = (s + t) >> 1;
        B_mark(p, s, t);
        if (l <= m) update(l, r, c, s, m, ls(p), op);
        if (r > m) update(l, r, c, m + 1, t, rs(p), op);
        d[p] = d[ls(p)] + d[rs(p)];
    }
    long long sum(long long l, long long r, long long s, long long t, long long p) {
        if (l <= s && t <= r)return d[p];
        long long m = (s + t) >> 1;
        B_mark(p, s, t);
        long long ret = 0;
        if (l <= m) ret += sum(l, r, s, m, ls(p));
        if (m < r)  ret += sum(l, r, m + 1, t, rs(p));
        return ret;
    }
    void operator()(long long n) {//上界
        build(1, n, 1);
    }
    lineTree() { ; };
};
lineTree t;
int main() {
    // freopen("in", "r", stdin);
    long long n, q, m;
    cin >> n >> m >> q;
    for (long long i = 1; i <= n; i++) {
        cin >> t.a[i];
    }
    t(n);
    long long opt, a, b, c;
    for (long long i = 1; i <= m; i++) {
        cin >> opt;
        if (opt == 1 || opt == 2) {
            cin >> a >> b >> c;
            t.update(a, b, c, 1, n, 1, opt);
        }
        else {
            cin >> a >> b;
            cout << t.sum(a, b, 1, n, 1) << endl;
        }
    }
    system("pause");
    return 0;
}

一个必要的链接

思路:延迟修改操作,然后在找到时再应用修改

拉了坨大的

2024/8/8 15:04
加载中...