0分求调
查看原帖
0分求调
891245
R_aier楼主2023/9/17 11:30
#include <bits/stdc++.h>
#define LOCAL
const int maxn = 5e5 + 10;
using namespace std;
int n, m;
int a[maxn];

struct FHQ_treap
{
    struct node
    {
        int ls = 0, rs = 0, st = 0, ed = 0;
        int val = 0, sum = 0, siz = 0;
        int lmax = 0, rmax = 0, max_sum = 0;
        int pos_tag = 0;
        bool inv_tag = 0;
        node() {}
        node(int st, int ed, int val) : st(st), ed(ed), val(val), siz(ed-st+1),sum(val * (st - ed + 1)),
        lmax(val <= 0 ? 0 : val * (st - ed + 1)), rmax(lmax), max_sum(sum) {}
    }t[maxn];
    int cnt, root, rubbish[maxn],top;
    int new_node(int st,int ed, int val)
    {
        if (top)
        {
            t[rubbish[top]] = node(st, ed, val);
            return rubbish[top--];
        }
        t[++cnt] = node(st, ed, val);
        return cnt;
    }
#define ls(u) (t[u].ls)
#define rs(u) (t[u].rs)
#define len(u) (t[u].ed - t[u].st + 1)
    int dep[maxn];
    void dfs(int u)
    {
        if (!u)
        {
            dep[u] = 0;
            return;
        }
        dep[ls(u)]=dep[rs(u)]=dep[u]+1;
        dfs(ls(u));dfs(rs(u));
    }
    int out(int rt)
    {
        cout<<endl<<endl;
        push_down(rt);
        dep[rt]=1;
        dfs(rt);
        queue<int> q;
        cout << t[rt].st<<" "<<t[rt].ed<<" " << t[rt].max_sum<<" ";
        if(ls(rt))
        q.push(ls(rt)),cout<<"l";
        if(rs(rt))
        q.push(rs(rt)),cout<<"r";
        cout<<endl;
        int ggb=3;
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            push_down(u);
            if (dep[u] == ggb)
            {
                cout << endl;
                ggb++;
            }
            cout << t[u].st << " " << t[u].ed << " " << t[u].max_sum << " ";
            if (t[u].ls)
                q.push(t[u].ls), cout << "l";
            if (t[u].rs)
                q.push(t[u].rs), cout << "r";
            cout<<"  ";
        }
        cout << endl
             << endl;
        return rt;
    }
    int move(int u,int k)
    {
        if (!u)
            return 0;
        t[u].pos_tag += k;
        t[u].st += k;
        t[u].ed += k;
        return u;
    }
    int inverse(int u)
    {
        if (!u)
            return 0;
        t[u].inv_tag ^= 1;
        t[u].st += t[rs(u)].siz - t[ls(u)].siz;
        t[u].ed += t[rs(u)].siz - t[ls(u)].siz;
        swap(t[u].lmax, t[u].rmax);
        move(ls(u), t[rs(u)].siz + len(u));
        move(rs(u), -len(u) - t[ls(u)].siz);
        return u;
    }
    void push_down(int u)
    {
        if(t[u].pos_tag)
        {
            move(ls(u), t[u].pos_tag);
            move(rs(u), t[u].pos_tag);
            t[u].pos_tag = 0;
        }
        if(t[u].inv_tag)
        {
            swap(ls(u),rs(u));
            inverse(ls(u));
            inverse(rs(u));
            t[u].inv_tag=0;
        }
    }
    void push_up(int u)
    {
        t[u].siz = t[ls(u)].siz + t[rs(u)].siz + len(u);
        t[u].sum = t[u].val * len(u) + t[ls(u)].sum + t[rs(u)].sum;
        if(ls(u)&&rs(u))
        {
            t[u].lmax = max(t[ls(u)].lmax, t[ls(u)].sum + t[rs(u)].lmax + t[u].val * len(u));
            t[u].rmax = max(t[rs(u)].rmax, t[rs(u)].sum + t[ls(u)].rmax + t[u].val * len(u));
            t[u].max_sum = max(max(t[ls(u)].max_sum, t[rs(u)].max_sum), t[ls(u)].rmax + t[rs(u)].lmax + len(u) * t[u].val);
        }
        else if(ls(u))
        {
            t[u].lmax = max(t[ls(u)].lmax, t[ls(u)].sum + t[u].val * len(u));
            t[u].rmax = max(0, t[ls(u)].rmax + t[u].val * len(u));
            t[u].max_sum = max(t[ls(u)].max_sum, t[ls(u)].rmax + len(u) * t[u].val);
        }
        else if(rs(u))
        {
            t[u].lmax = max(0, t[rs(u)].lmax + t[u].val * len(u));
            t[u].rmax = max(t[rs(u)].rmax, t[rs(u)].sum + t[u].val * len(u));
            t[u].max_sum = max(t[rs(u)].max_sum, t[rs(u)].lmax + len(u) * t[u].val);
        }
        else
        {
            t[u].lmax = t[u].rmax = max(0, t[u].val * len(u));
            t[u].max_sum = t[u].val <= 0 ? t[u].val : t[u].val * len(u);
        }
    }
    int merge(int l, int r)
    {
        if (!l || !r)
            return l + r;
        if (rand() & 1)
        {
            //cout << l << endl;
            push_down(l);
            rs(l) = merge(rs(l), r);
            push_up(l);
            return l;
        }
        else
        {
            //cout << r << endl;
            push_down(r);
            ls(r) = merge(l, ls(r));
            push_up(r);
            return r;
        }
    }
    void push_rubbish(int u)
    {
        if(!u) return;
        push_rubbish(ls(u));
        rubbish[++top] = u;
        push_rubbish(rs(u));
    }
    int clap(int rt,int val)
    {
        push_rubbish(rt);
        return new_node(1, t[rt].siz, val);
    }
    void split(int u,int pos,int &l,int &r)
    {
        if (!u)
        {
            l = r = 0;
            return;
        }
        push_down(u);
        if(pos<t[u].st)
        {
            r = u;
            split(ls(u), pos, l, ls(u));
        }
        else if(pos<=t[u].ed)
        {
            if(pos==t[u].st)
            {
                l=ls(u);
                ls(u)=0;
                r=u;
            }
            else
            {
                l = u;
                r = new_node(pos, t[u].ed, t[u].val);
                t[l].ed = pos - 1;
                t[r].rs = t[u].rs;
                t[l].rs = 0;
                push_up(l);
                push_up(r);
                return ;
            }
        }
        else
        {
            l = u;
            split(rs(u), pos, rs(u), r);
        }
        push_up(u);
    }
    int build(int l,int r,int pos)
    {
        if(l>r) return 0;
        int mid = (l + r) >> 1;
        int u = new_node(mid + pos, mid + pos, a[mid]);
        ls(u) = build(l, mid - 1, pos);
        rs(u) = build(mid + 1, r, pos);
        push_up(u);
        return u;
    }
    void insert(int pos,int num)
    {
        int l, r;
        split(root, pos + 1, l, r);
        root = merge(merge(l, build(1, num, pos)), move(r, num));
    }
    void delet(int pos,int num)
    {
        int l, r, p;
        split(root, pos, l, p);
        split(p, pos + num, p, r);
        push_rubbish(p);
        root = merge(l, move(r, -num));
    }
    void reverse(int pos,int num)
    {
        int l, r, p;
        split(root, pos, l, p);
        split(p, pos + num, p, r);
        inverse(p);
        root = merge(merge(l, p), r);
    }
    void assign(int pos,int num,int val)
    {
        int l, r, p;
        split(root, pos, l, p);
        split(p, pos + num, p, r);
        root = merge(merge(l, move(clap(p, val), pos-1)), r);
    }
    int query_max_sum(int pos, int num)
    {
        int l, r, p;
        split(root, pos, l, p);
        split(p, pos + num, p, r);
        int res = t[p].max_sum;
        root = merge(merge(l, p), r);
        return res;
    }
    int query_sum(int pos, int num)
    {
        int l, r, p;
        split(root, pos, l, p);
        split(p, pos + num, p, r);
        int res = t[p].sum;
        root = merge(merge(l, p), r);
        return res;
    }
    int get(int pos)
    {
        int l, r, p;
        split(root, pos, l, r);
        p=r;
        while (ls(p))
            push_down(p),
            p=ls(p);
        int res = t[p].val;
        root = merge(l, r);
        return res;
    }
    int query_max_sum()
    {
        return t[root].max_sum;
    }
    void out()
    {
        out(root);
        cout << endl;
    }
} t;

char opt[10];
void solve()
{
    t.out();
    int pos, num, val;
    while (m--)
    {
        scanf("%s", opt + 1);
        switch (opt[1])
        {
        case 'I':
            scanf("%d%d", &pos, &num);
            for (int i = 1; i <= num; ++i)
                scanf("%d", &a[i]);
            t.insert(pos, num);
            break;
        case 'D':
            scanf("%d%d", &pos, &num);
            t.delet(pos, num);
            break;
        case 'R':
            scanf("%d%d", &pos, &num);
            t.reverse(pos, num);
            break;
        case 'M':
            if (opt[3] == 'K')
            { // assign
                scanf("%d%d%d", &pos, &num, &val);
                t.assign(pos, num, val);
            }
            else
            { // query max sum
                scanf("%d%d", &pos, &num);
                //printf("%d\n", t.query_max_sum(pos, num));
                printf("%d\n", t.query_max_sum());
            }
            break;
        case 'G':
            if (opt[4] == '-')
            { // get sum
                scanf("%d%d", &pos, &num);
                printf("%d\n", t.query_sum(pos, num));
            }
            else
            { // get x
                scanf("%d", &pos);
                printf("%d\n", t.get(pos));
            }
            break;
        }
        //t.out();
    }
}
void init()
{
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    t.insert(0, n);
}
int main()
{
#ifdef LOCAL
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
#endif
    init();
    solve();
}
2023/9/17 11:30
加载中...