萌新求调玄学代码
查看原帖
萌新求调玄学代码
891245
R_aier楼主2023/10/20 12:08

好像是push写错了,但我太菜,不知道错在哪了。

调样例一时答案随机改变。。

// code by aier
//  think twice,code once!
#include <bits/stdc++.h>
#define AC return 0;
using namespace std;
const int maxn = 1e5 + 10;
int n, m;
int a[maxn];
char getc()
{
    static char buf[maxn << 3], *s, *t;
    return (s == t) && (t = (s = buf) + fread(buf, 1, maxn << 3, stdin)), (s == t) ? EOF : *s++;
}
void read(int &x)
{
    x = 0;
    bool f = 0;
    char ch = getc();
    while (!isdigit(ch))
    {
        if (ch == '-')
            f = 1;
        ch = getc();
    }
    while (isdigit(ch))
    {
        x = x * 10 + ch - '0';
        ch = getc();
    }
    f ? x = -x : 0;
}
mt19937 mt(time(NULL));
struct treap
{
    struct node
    {
        int ls, rs;
        int siz, val, len;
        int sum, tagl, tagk;
        int pri;
        node() : ls(0), rs(0), siz(0), val(0), len(0), tagl(0), tagk(0) {}
        node(int val, int len = 1) : siz(1), len(len), val(val), pri(mt()), sum(val * len), ls(0), rs(0), tagl(0), tagk(0) {}
    } t[maxn << 2];
    int rt, cnt;
#define ls(u) t[u].ls
#define rs(u) t[u].rs
#define siz(u) t[u].siz
#define val(u) t[u].val
#define tagl(u) t[u].tagl
#define tagk(u) t[u].tagk
#define pri(u) t[u].pri
#define sum(u) t[u].sum
#define len(u) t[u].len
    int new_node(int val, int len = 1)
    {
        t[++cnt] = node(val, len);
        return cnt;
    }
    void push_up(int u)
    {
        siz(u) = siz(ls(u)) + siz(rs(u)) + len(u);
        sum(u) = sum(ls(u)) + sum(rs(u)) + val(u) * len(u);
    }
    int bulid(int l, int r)
    {
        if (l > r)
            return 0;
        int mid = (l + r) >> 1;
        int u = new_node(a[mid]);
        ls(u) = bulid(l, mid - 1);
        rs(u) = bulid(mid + 1, r);
        push_up(u);
        return u;
    }
    void bulid()
    {
        rt = bulid(1, n);
    }
    // l: 每一项额外加的值
    // k: 后续每一项加的值
    void addtag(int u, int l, int k)
    {
        if (!u)
            return;
        sum(u) += siz(u) * l + ((siz(u) * (siz(u) + 1)) >> 1) * k;
        tagl(u) += l;
        tagk(u) += k;
        val(u) += l + (siz(ls(u)) + 1) * k;
    }
    void push_down(int u)
    {
        if (tagk(u) && tagl(u))
        {
            if (ls(u))
                addtag(ls(u), tagl(u), tagk(u));
            if (rs(u))
                addtag(rs(u), tagl(u) + (siz(ls(u)) + len(u)) * tagk(u), tagk(u));
            tagk(u) = tagl(u) = 0;
        }
    }
    int merge(int l, int r)
    {
        if (!l || !r)
            return l + r;
        if (pri(l) < pri(r))
        {
            push_down(l);
            rs(l) = merge(rs(l), r);
            push_up(l);
            return l;
        }
        else
        {
            push_down(r);
            ls(r) = merge(l, ls(r));
            push_up(r);
            return r;
        }
    }
    // 返回值分为三部分
    // l:siz<=x   r:siz<siz(u)-x
    // 返回len跨过x的节点(如果有)
    int split(int u, int x, int &l, int &r)
    {
        if (!u)
        {
            l = r = 0;
            return 0;
        }
        push_down(u);
        if (siz(ls(u)) + len(u) < x)
        {
            l = u;
            int tmp = split(rs(u), x - siz(ls(u)) - len(u), rs(u), r);
            push_up(u);
            return tmp;
        }
        else if (siz(ls(u)) > x)
        {
            r = u;
            int tmp = split(ls(u), x, l, ls(u));
            push_up(u);
            return tmp;
        }
        else
        {
            int tmp = 0;
            if (siz(ls(u)) + len(u) == x)
            {
                l = u;
                r = rs(u);
                rs(u) = 0;
            }
            else if (siz(ls(u)) == x)
            {
                r = u;
                l = ls(u);
                ls(u) = 0;
            }
            else
            {
                l = ls(u);
                r = rs(u);
                ls(u) = rs(u) = 0;
                tmp = u;
            }
            push_up(u);
            return tmp;
        }
    }
    // siz(l)=x
    // siz(r)=siz(rt)-x
    void split_(int u, int x, int &l, int &r)
    {
        int tmp = split(u, x, l, r);
        if (tmp)
        {
            x -= siz(l);
            int _ = new_node(val(tmp), len(tmp) - x);
            len(tmp) = x;
            push_up(tmp);
            l = merge(l, tmp);
            r = merge(_, r);
        }
    }
    void assign(int l, int r, int k)
    {
        int l_, r_, p;
        split_(rt, l - 1, l_, p);
        split_(p, r - l + 1, p, r_);
        rt = merge(l_, merge(new_node(k, siz(p)), r_));
    }
    void add(int l, int r, int k)
    {
        int l_, r_, p;
        split_(rt, l - 1, l_, p);
        split_(p, r - l + 1, p, r_);
        addtag(p, 0, k);
        rt = merge(l_, merge(p, r_));
    }
    void insert(int pos, int val)
    {
        int l, r;
        split_(rt, pos - 1, l, r);
        rt = merge(l, merge(new_node(val), r));
    }
    int query(int l, int r)
    {
        int l_, r_, p;
        split_(rt, l - 1, l_, p);
        split_(p, r - l + 1, p, r_);
        int res = sum(p);
        rt = merge(l_, merge(p, r_));
        return res;
    }
};
treap t;
void solve()
{
    while (m--)
    {
        int opt, l, r, k;
        read(opt);
        switch (opt)
        {
        case 1:
            read(l);
            read(r);
            read(k);
            t.assign(l, r, k);
            break;
        case 2:
            read(l);
            read(r);
            read(k);
            t.add(l, r, k);
            break;
        case 3:
            read(l);
            read(k);
            t.insert(l, k);
            break;
        case 4:
            read(l);
            read(r);
            printf("%d\n", t.query(l, r));
            break;
        }
    }
}
void init()
{
    read(n);
    read(m);
    for (int i = 1; i <= n; ++i)
        read(a[i]);
    t.bulid();
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
    freopen("out.out", "w", stdout);
#endif
    init();
    solve();
    AC
}

帮帮萌新吧

2023/10/20 12:08
加载中...