RE on #11#19求调

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

yangzichen1203 @ 2024-01-26 13:14:26

#include<bits/stdc++.h>
using namespace std;
#define For(i,j,k) for(int i=j;i<=k;i++)
#define dFor(i,j,k) for(int i=j;i>=k;i--)
#define int long long
template<typename T> inline void read(T &ff){
    T rr=1;ff=0;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')rr=-1;ch=getchar();}
    while(isdigit(ch)){ff=(ff<<1)+(ff<<3)+(ch^48);ch=getchar();}
    ff*=rr;
}
template<typename T> inline void write(T x){
    int a[40],cnt=0;
    if(x==0) putchar('0');
    if(x<0){putchar('-');x=-x;}
    while(x){a[cnt++]=x%10;x/=10;}
    for(int i=cnt-1;i>=0;i--) putchar(a[i]+'0');
    putchar('\n');
}
struct Node{
    Node *ch[2];
    int val,rank;
    int rep_cnt;
    int siz;
    Node(int val):val(val),rep_cnt(1),siz(1){
        ch[0]=ch[1]=nullptr;
        rank=rand();
    }
    inline void upd_siz(){
        siz=rep_cnt;
        if(ch[0]!=nullptr) siz+=ch[0]->siz;
        if(ch[1]!=nullptr) siz+=ch[1]->siz;
    }
};
class Treap{
    private:
        Node *root;
        int q_prev_tmp=0,q_nex_tmp=0;
        inline void _rotate(Node *&cur,bool type){//type=0为右旋,type=1为左旋
            Node *tmp=cur->ch[type];
            cur->ch[type]=tmp->ch[!type];
            tmp->ch[!type]=cur;
            tmp->upd_siz();cur->upd_siz();
            cur=tmp;
            /*        A                 C
            *        / \               / \
            *       B  C   <----->    A   E
            *         / \            / \
            *        D   E          B   D
            */
        }
        void _insert(Node *&cur,int val){
            if(cur==nullptr){
                cur=new Node(val);
                return;
            }else if(val==cur->val){
                cur->rep_cnt++;
                cur->siz++;
            }else if(val<cur->val){
                _insert(cur->ch[0],val);
                if(cur->ch[0]->rank<cur->rank){
                    _rotate(cur,0);
                }
                cur->upd_siz();
            }else{
                _insert(cur->ch[1],val);
                if(cur->ch[1]->rank<cur->rank){
                    _rotate(cur,1);
                }
                cur->upd_siz();
            }
        }
        void _del(Node *&cur,int val){
            if(val>cur->val){
                _del(cur->ch[1],val);
                cur->upd_siz();
            }else if(val<cur->val){
                _del(cur->ch[0],val);
                cur->upd_siz();
            }else{
                if(cur->rep_cnt>1){
                    cur->rep_cnt--;
                    cur->siz--;
                    return ;
                }
                Node *tmp=cur;
                if(cur->ch[0]==nullptr){
                    if(cur->ch[1]==nullptr){
                        delete cur;
                        cur=nullptr;
                    }else{
                        cur=tmp->ch[1];
                        delete tmp;
                    }
                }else{
                    if(cur->ch[1]==nullptr){
                        cur=tmp->ch[0];
                        delete tmp;
                    }else{
                        bool type=cur->ch[0]->rank>cur->ch[1]->rank;
                        _rotate(cur,type);
                        _del(cur->ch[!type],val);
                        cur->upd_siz();
                    }
                }
            }
        }
        int _query_rank(Node *cur,int val){
            int less_siz=cur->ch[0]==nullptr?0:cur->ch[0]->siz;
            if(val==cur->val){
                return less_siz+1;
            }else if(val<cur->val){
                if(cur->ch[0]!=nullptr){
                    return _query_rank(cur->ch[0],val);
                }else{
                    return 1;
                }
            }else{
                if(cur->ch[1]!=nullptr){
                    return less_siz+cur->rep_cnt+_query_rank(cur->ch[1],val);
                }else{
                    return cur->siz+1;
                }
            }
            return -1;
        }
        int _query_val(Node *cur,int rank){
            int less_siz=cur->ch[0]==nullptr?0:cur->ch[0]->siz;
            if(rank<=less_siz){
                return _query_val(cur->ch[0],rank);
            }else if(rank<=less_siz+cur->rep_cnt){
                return cur->val;
            }else{
                return _query_val(cur->ch[1],rank-less_siz-cur->rep_cnt);
            }
            return -1;
        }
        int _query_prev(Node *cur,int val){
            if(val<=cur->val){
                if(cur->ch[0]!=nullptr){
                    return _query_prev(cur->ch[0],val);
                }
            }else{
                q_prev_tmp=cur->val;
                if(cur->ch[1]!=nullptr) _query_prev(cur->ch[1],val);
                return q_prev_tmp;
            }
            return -1;
        }
        int _query_nex(Node *cur,int val){
            if(val>=cur->val){
                if(cur->ch[1]!=nullptr){
                    return _query_nex(cur->ch[1],val);
                }
            }else{
                q_nex_tmp=cur->val;
                if(cur->ch[0]!=nullptr) _query_nex(cur->ch[0],val);
                return q_nex_tmp;
            }
            return -1;
        }
    public:
        void insert(int val){
            _insert(root,val);
        }
        void del(int val){
            _del(root,val);
        }
        int query_rank(int val){
            return _query_rank(root,val);
        }
        int query_val(int rank){
            return _query_val(root,rank);
        }
        int query_prev(int val){
            return _query_prev(root,val);
        }
        int query_nex(int val){
            return _query_nex(root,val);
        }
};
Treap tr;
signed main(){
    srand(time(0));
    ios::sync_with_stdio(false);
    cout.tie(0);
    int n,m;
    read(n);read(m);
    For(i,1,n){
        int x;
        read(x);
        tr.insert(x);
    }
    int last=0,ans=0;
    while(m--){
        int op,x;
        read(op);read(x);
        x^=last;
        if(op==1){
            tr.insert(x);
        }else if(op==2){
            tr.del(x);
        }else if(op==3){
            last=tr.query_rank(x);
            ans^=last;
        }else if(op==4){
            last=tr.query_val(x);
            ans^=last;
        }else if(op==5){
            last=tr.query_prev(x);
            ans^=last;
        }else if(op==6){
            last=tr.query_nex(x);
            ans^=last;
        }
    }
    cout<<ans<<endl;
    return 0;
}

by dongzhen @ 2024-02-01 20:27:28

你说的很对,但是这道题数据可能毒瘤,而且请消化完oiwiki的再复制. 每一个成员函数开始加一个特判是否==NULL 是每一个!可以看看这个链接 RE92: https://www.luogu.com.cn/record/145660975 AC:https://www.luogu.com.cn/record/145661940


|