treap板子玄关求调

P6136 【模板】普通平衡树(数据加强版)

apple_vinegar @ 2024-11-06 16:05:03

#include<bits/stdc++.h>
#define int long long
#define mid ((l+(r-l)>>1))
#define ls (p<<1)
#define rs (ls|1)
#define lt ls,l,mid
#define rt rs,mid,r
using namespace std;
const int INF=1e15,N=1e5+5;
int last,tot,root,ans;

inline int read(){
    int a=1,b=0;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') a=-a;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        b=(b<<1)+(b<<3)+(ch^48);
        ch=getchar();
    }
    return a*b;
}

struct node{
    int l,r;
    int val,dat;
    int cnt,size;
};
node a[N];

inline int add(int val){
    a[++tot].val=val;
    a[tot].dat=rand();
    a[tot].cnt=a[tot].size+1;
    return tot;
}

inline void update(int p){
    a[p].size=a[a[p].l].size+a[a[p].r].size+a[p].cnt;
}

inline void build(){
    add(-INF),add(INF);
    root=1,a[1].r=2;
    update(root);
}

inline void zig(int &p){//right
    int q=a[p].l;
    a[p].l=a[q].r;
    a[q].r=p;
    p=q;
    update(a[p].r),update(p);
}

inline void zag(int &p){//left
    int q=a[p].r;
    a[p].r=a[q].l;
    a[q].l=p;
    p=q;
    update(a[p].l),update(p);
}

inline void insert(int &p,int val){
    if(p==0){
        p=add(val);
        return;
    }
    if(val==a[p].val){
        a[p].cnt++;
        update(p);
        return ;
    }
    if(val<a[p].val){
        insert(a[p].l,val);
        if(a[p].dat<a[a[p].l].dat){
            zig(p);
        }
    }
    else{
        insert(a[p].r,val);
        if(a[p].dat<a[a[p].r].dat) zag(p);
    }
    update(p);
}

inline void remove(int &p,int val){
    if(p==0) return ;
    if(val==a[p].val){
        if(a[p].cnt>1){
            a[p].cnt--;
            update(p);
            return;
        }
        if(a[p].l||a[p].r){
            if(!a[p].l||a[a[p].l].dat>a[a[p].r].dat){
                zig(p);
                remove(a[p].r,val);
            }
            else{
                zag(p);
                remove(a[p].l,val);
            }
            update(p);
        }
        else p=0;
        return;
    }
    if(val<a[p].val) remove(a[p].l,val);
    else remove(a[p].r,val);
    update(p);
}

inline int findrank(int p,int val){
    if(p==0) return 0;
    if(val==a[p].val) return a[a[p].l].size+1;
    if(val<a[p].val) return findrank(a[p].l,val);
    else return findrank(a[p].r,val)+a[a[p].l].size+a[p].cnt;
}

inline int findwho(int p,int rank){
    if(p==0) return INF;
    if(a[a[p].l].size>=rank) return findwho(a[p].l,rank);
    if(a[a[p].l].size+a[p].cnt>=rank) return a[p].val;
    return findwho(a[p].r,rank-a[a[p].l].size-a[p].cnt);
}

inline int getpre(int val){
    int ans=1;
    int p=root;
    while(p){
        if(val==a[p].val){
            if(a[p].l>0){
                p=a[p].l;
                while(a[p].r>0) p=a[p].r;
                ans=p;
            }
            break;
        }
        if(a[p].val<val&&a[p].val>a[ans].val) ans=p;
        if(val<a[p].val) p=a[p].l;
        else p=a[p].r;
    }
    return a[ans].val;
}

inline int getnext(int val){
    int ans=2;
    int p=root;
    while(p){
        if(val==a[p].val){
            if(a[p].r>0){
                p=a[p].r;
                while(a[p].l>0) p=a[p].l;
                ans=p;
            }
            break;
        }
        if(a[p].val>val&&a[p].val<a[ans].val) ans=p;
        if(val<a[p].val) p=a[p].l;
        else p=a[p].r;
    }
    return a[ans].val;
}

signed main(){
    // freopen("a","w",stdout);
    srand(time(0));
    int n=read(),m=read();

    build();
    for(int i=1;i<=n;i++) insert(root,read());
    while(m--){
        int op=read(),x=read();
        x^=last;
        if(op==1){
            insert(root,x);
        }
        if(op==2){
            remove(root,x);
        }
        if(op==3){
            last=(findrank(root,x)-1);
        }
        if(op==4){
            last=findwho(root,x+1);
        }
        if(op==5){
            last=getpre(x);
        }
        if(op==6){
            last=getnext(x);
        }
        cout<<last<<endl;
        if(op>=3) ans^=last;
        // cout<<last<<endl;
    }
    cout<<ans;
    return 0;
}

by lyc20130626 @ 2024-11-06 16:07:09

#include <iostream>
#include <bits/extc++.h>
#define int long long
using namespace __gnu_pbds;
using namespace std;

int n, q, ans, last;

tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> t;

signed main() {
  ios :: sync_with_stdio(0), cin.tie(0);
  cin >> n >> q;
  for ( int i = 1, x; i <= n; ++i ) {
    cin >> x;
    t.insert(x);
  }
  while (q--) {
    int op, x;
    cin >> op >> x;
    x ^= last;
    if (op == 1) {
      t.insert(x);
    } else if (op == 2) {
      t.erase(t.upper_bound(x));
    } else if (op == 3) {
      ans ^= t.order_of_key(x) + 1;
      last = t.order_of_key(x) + 1;
    } else if (op == 4) {
      ans ^= *t.find_by_order(x - 1);
      last = *t.find_by_order(x - 1);
    } else if (op == 5) {
      ans ^= *prev(t.upper_bound(x));
      last = *prev(t.upper_bound(x));
    } else if (op == 6) {
     ans ^= *t.lower_bound(x);
     last = *t.lower_bound(x);
    }
  }
  cout << ans;
  return 0;
}

by lyc20130626 @ 2024-11-06 16:08:19

@penggc16801 你这个代码有点长


by apple_vinegar @ 2024-11-06 16:12:46

@lyc20130626 e~可以不用平板电视吗,主要是练treap的


by lyc20130626 @ 2024-11-06 16:12:52

@complete_binary_tree 又遇见了


by complete_binary_tree @ 2024-11-06 16:15:21

呸什么 set

不过也一样,C++ 的类 set,map 数据结构都是红黑树实现的,不是 treap


by apple_vinegar @ 2024-11-06 16:19:36

@complete_binary_tree dalao求调


by complete_binary_tree @ 2024-11-06 16:37:32

@penggc16801 不会 treap,用 splay 过的:(


by Hagasei @ 2024-11-06 16:39:35

@penggc16801 总有人喜欢粘个题解过来找存在感,别管就是了。


by Hagasei @ 2024-11-06 16:39:45

我帮你看看吧


by apple_vinegar @ 2024-11-06 16:42:14

@Hagasei orz


| 下一页