萌新初学 FHQ-Treap 球调
查看原帖
萌新初学 FHQ-Treap 球调
105230
Doubeecat楼主2021/12/16 21:53

孩子调了四节课 已经麻了

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cctype>
#include <vector>
#include <ctime>
#include <cmath>
using namespace std;
#define ll long long
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define pii pair<int,int>
#define mp make_pair

char buf[1 << 20], *p1, *p2;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2)?EOF: *p1++)
template <typename T> inline void read(T &t) {
	int v = getchar();T f = 1;t = 0;
	while (!isdigit(v)) {if (v == '-')f = -1;v = getchar();}
	while (isdigit(v)) {t = t * 10 + v - 48;v = getchar();}
	t *= f;
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
	read(t);read(args...);
}

const int N = 1e6 + 10;

struct node {
    int ls,rs;
    int ans,val,rnd,lsum,rsum,tag1,tag2,sum,cnt;
}tree[N];

int tot,root,n,m,a[N],st[N],top;

int randint() {
    return rand() * rand() % 998244353;
}

int newnode(int val) {
    int pos;
    if (!top) pos = ++tot;
    else pos = st[top--];
    tree[pos].val = val;
    tree[pos].ls = tree[pos].rs = tree[pos].tag1 = tree[pos].tag2 = 0;
    tree[pos].lsum = tree[pos].rsum = max(0,val);
    tree[pos].ans = val;
    tree[pos].sum = val;
    tree[pos].cnt = 1;
    tree[pos].rnd = randint();
    return pos;
}

void pushup(int p) {
    tree[p].cnt = (tree[tree[p].ls].cnt + tree[tree[p].rs].cnt + 1);
    tree[p].lsum = max(0,max(tree[tree[p].ls].lsum,tree[tree[p].ls].sum + tree[tree[p].rs].lsum + tree[p].val));
    tree[p].rsum = max(0,max(tree[tree[p].rs].rsum,tree[tree[p].rs].sum + tree[tree[p].ls].rsum + tree[p].val));
    tree[p].ans = max(tree[p].val,tree[p].val + max(0,tree[tree[p].ls].rsum + tree[tree[p].rs].lsum));
    tree[p].sum = tree[tree[p].ls].sum + tree[tree[p].rs].sum + tree[p].val;
    if (tree[p].ls) tree[p].ans = max(tree[p].ans,tree[tree[p].ls].ans);
    if (tree[p].rs) tree[p].ans = max(tree[p].ans,tree[tree[p].rs].ans);
}

void cover(int p,int val) {
    tree[p].val = val;
    tree[p].sum = tree[p].cnt * val;
    tree[p].lsum = tree[p].rsum = max(0,tree[p].sum);
    tree[p].ans = max(val,tree[p].sum);
    tree[p].tag2 = 1;
}

void pushdown(int p) {
    if (tree[p].tag1) {
        swap(tree[p].ls,tree[p].rs);
        swap(tree[p].lsum,tree[p].rsum);
        if (tree[p].ls) tree[tree[p].ls].tag1 ^= 1;
        if (tree[p].rs) tree[tree[p].rs].tag1 ^= 1;
        tree[p].tag1 = 0;
    }
    if (tree[p].tag2) {
        cover(tree[p].ls,tree[p].val);
        cover(tree[p].rs,tree[p].val);
        tree[p].tag2 = 0;
    }
}

void split(int p,int val,int &x,int &y) {
    if (!p) {
        x = y = 0;
        return ;
    }
    pushdown(p);
    if (val > tree[tree[p].ls].cnt) {
        x = p;
        split(tree[p].rs,val - tree[tree[p].ls].cnt - 1,tree[p].rs,y);
    } else {
        y = p;
        split(tree[p].ls,val,x,tree[p].ls);
    }
    pushup(p);
}

int merge(int x,int y) {
    if (!x || !y) {
        return x + y;
    }
    if (tree[x].rnd < tree[y].rnd) {
        pushdown(x);
        tree[x].rs = merge(tree[x].rs,y);
        pushup(x);
        return x;
    } else {
        pushdown(y);
        tree[y].ls = merge(x,tree[y].ls);
        pushup(y);
        return y;
    }
}

int x,y,z;

void release(int p) {
    if (!tree[p].ls && !tree[p].rs) {
        st[++top] = p;
        return ;
    }
    st[++top] = p;
    if (tree[p].ls) release(tree[p].ls);
    if (tree[p].rs) release(tree[p].rs);
}

void del(int val,int len) {
    split(root,val - 1,x,y);
    split(y,len,y,z);
    release(y);
    root = merge(x,z);
}

void change(int pos,int len,int k) {
    split(root,pos - 1,x,y);
    split(y,len,y,z);
    cover(y,k);
    root = merge(x,merge(y,z));
}

void reverse(int pos,int len) {
    split(root,pos - 1,x,y);
    split(y,len,y,z);
    tree[y].tag1 = 1;
    root = merge(x,merge(y,z));
}   

int query1(int pos,int len) {
    split(root,pos - 1,x,y);
    split(y,len,y,z);
    int ans = tree[y].sum;
    root = merge(x,merge(y,z));
    return ans;
}

int query2() {
    pushdown(root);
    pushup(root);
    return tree[root].ans;
}

int build(int l,int r) {
    if (l == r) {
        return newnode(a[l]);
    }
    int mid = (l + r) >> 1;
    return merge(build(l,mid),build(mid + 1,r));
}

void insert(int pos,int cnt) {
    for (int i = 1;i <= cnt;++i) cin >> a[i];
    split(root,pos,x,y);
    z = build(1,cnt);
    root = merge(merge(x,z),y);
}

void debug(int p) {
    if (!tree[p].ls && !tree[p].rs) {
        printf("%d ",tree[p].cnt);
        return ;
    }
    if (tree[p].ls) debug(tree[p].ls);
    printf("%d ",tree[p].cnt);
    if (tree[p].rs) debug(tree[p].rs);
}

signed main() {
    FO(P2042_2)
    srand((unsigned)time(0));
    //ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= n;++i) cin >> a[i];
    root = build(1,n);
    for (int i = 1;i <= m;++i) {
        char s[50];cin >> s;
        //cout << s << endl;
        if (s[0] == 'I') {
            int pos,cnt;cin >> pos >> cnt;
            //puts("1");
            insert(pos,cnt);
        } else if (s[0] == 'D') {
            int pos,cnt;cin >> pos >> cnt;
            //puts("2");
            del(pos,cnt);
        } else if (s[0] == 'M') {
            if (s[2] == 'K') {
                int pos,cnt,k;cin >> pos >> cnt >> k;
                change(pos,cnt,k);
            //puts("3");
            } else {
                printf("%d\n",query2());
            //puts("6");
            }
        } else if (s[0] == 'R'){
            int pos,cnt;cin >> pos >> cnt;
            //puts("4");
            reverse(pos,cnt);
        } else {
            int pos,cnt;cin >> pos >> cnt;
            //puts("5");
            printf("%d\n",query1(pos,cnt));
        }
        //debug(root);
        //puts("
    }
}
2021/12/16 21:53
加载中...