求助fhq treap
查看原帖
求助fhq treap
567054
Catium楼主2022/7/28 16:39

不能正确计算答案

// fhq Threap
// 按照下标分裂
#include <iostream>
using namespace std;
#define N 100100

#define siz(x) tr[x].siz
#define sum(x) tr[x].sum
#define val(x) tr[x].val

#define ls(x) tr[x].ls
#define rs(x) tr[x].rs

struct node {
    int val = 0;
    int add = 0;
    int sum = 0;
    int siz = 1;
    int w = 0;
    int ls, rs;
};
node tr[N];
inline void pushup(int x) {
    siz(x) = siz(ls(x)) + siz(rs(x)) + 1;
    sum(x) = sum(ls(x)) + sum(rs(x)) + val(x);
}
inline void pushdown(int x) {
    if (ls(x)) {
        sum(ls(x)) += siz(ls(x)) * tr[x].add;
        val(ls(x)) += tr[x].add;
        tr[ls(x)].add += tr[x].add;
    }
    if (rs(x)) {
        sum(rs(x)) += siz(rs(x)) * tr[x].add;
        val(rs(x)) += tr[x].add;
        tr[rs(x)].add += tr[x].add;
    }
    tr[x].add = 0;
}
void split(int x, int k, int& va, int& vb) {
    if (!x) {
        va = vb = 0;
        return;
    }
    pushdown(x);
    if (siz(ls(x)) < k) {
        va = x;
        // split(rs(x), k - (siz(ls(x)) + 1), rs(x), vb);
        split(rs(x), k - siz(ls(x)) - 1, rs(x), vb);
    } else {
        vb = x;
        split(ls(x), k, va, ls(x));
    }
    pushup(x);
}
int merge(int x, int y) {
    if (!x || !y) {
        return x | y;
    }
    if (tr[x].w <= tr[y].w) {
        pushdown(x);
        rs(x) = merge(rs(x), y);
        pushup(x);
        return x;
    } else {
        pushdown(y);
        ls(y) = merge(x, ls(y));
        pushup(y);
        return y;
    }
}
int tot = 0;
inline int nn(int k) {
    tot++;
    sum(tot) = k;
    val(tot) = k;
    siz(tot) = 1;
    tr[tot].w = rand();
    return tot;
}
int a[N];
int n;
int root = 0;
inline void add(int l, int r, int k) {
    int a, b, c;
    split(root, l - 1, a, b);
    split(b, r - l + 1, b, c);
    //现在a=[1,l-1],b=[l,r],c=[r+1,n];
    sum(b) += k * siz(b);
    val(b) += k;
    tr[b].add += k;
    root = merge(merge(a, b), c);
}
int qsum(int l, int r) {
    int a, b, c;
    split(root, l - 1, a, b);
    split(b, r - l + 1, b, c);
    int ret = tr[b].sum;
    root = merge(merge(a, b), c);
    return ret;
}
int m;
signed main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        root = merge(root, nn(a[i]));
    }
    for (int i = 1; i <= m; i++) {
        int o;
        cin >> o;
        if (o == 1) {
            int x, y, k;
            cin >> x >> y >> k;
            add(x, y, k);
        } else {
            int x, y;
            cin >> x >> y;
            cout << qsum(x, y) << endl;
            // cout << tr[root].sum << endl;
        }
        // cout << root << " " << sum(root) << endl;
    }
    return 0;
}
2022/7/28 16:39
加载中...