splay求调,样例过不去
查看原帖
splay求调,样例过不去
437398
EastIsRed楼主2024/4/11 16:14
#include<cstdio>
#include<algorithm>
#include<vector>
template<typename T>
class rope_based_on_splay{
    private:
        struct node{
            T val;
            node *fa,*son[2];
            size_t cnt,size;
            bool reverse_tag;
            node(const T& _val):val(_val),fa(nullptr),son{nullptr,nullptr},cnt(1ULL),size(1ULL),reverse_tag(false){}
            bool is_rs()
            {
                return this==fa->son[1];
            }
            void recalc_size()
            {
                size=(son[0]==nullptr?0ULL:son[0]->size)+cnt+(son[1]==nullptr?0ULL:son[1]->size);
            }
            void reverse()
            {
                reverse_tag=!reverse_tag;
                std::swap(son[0],son[1]);
            }
            void lzd_down()
            {
                if(reverse_tag)
                {
                    if(son[0]!=nullptr)
                        son[0]->reverse();
                    if(son[1]!=nullptr)
                        son[1]->reverse();
                    reverse_tag=false;
                }
            }
        }*root;
        void rotate(node* now)
        {
            if(now==nullptr||now->fa==nullptr)
                return;
            node *fa=now->fa,*anc=fa->fa;
            if(anc!=nullptr)
                anc->lzd_down();
            fa->lzd_down();
            now->lzd_down();
            bool is_rs=now->is_rs();
            fa->son[is_rs]=now->son[!is_rs];
            if(now->son[!is_rs]!=nullptr)
                now->son[!is_rs]->fa=fa;
            now->son[!is_rs]=fa;
            fa->fa=now;
            now->fa=anc;
            if(anc!=nullptr)
                anc->son[fa==anc->son[1]]=now;
            fa->recalc_size();
            now->recalc_size();
        }
        void splay(node* now,node* goal=nullptr)
        {
            if(goal==nullptr)
                root=now;
            while(now->fa!=goal)
            {
                node *fa=now->fa,*anc=now->fa->fa;
                if(anc!=nullptr)
                    anc->lzd_down();
                fa->lzd_down();
                now->lzd_down();
                if(anc!=goal)
                {
                    if(fa->is_rs()==now->is_rs())
                        rotate(now);
                    else rotate(fa);
                }
                rotate(now);
            }
        }
        void destroy(node* now)
        {
            if(now==nullptr)
                return;
            destroy(now->son[0]);
            destroy(now->son[1]);
            delete(now);
        }
        node* find_by_rank_base(size_t rk,node *goal=nullptr)
        {
            node* now=root;
            while(1)
            {
                if(now==nullptr)
                    fprintf(stderr,"Warning: Function find_by_rank_base is using an empty ptr\n");
                now->lzd_down();
                size_t l_siz=(now->son[0]==nullptr?0ULL:now->son[0]->size);
                if(now->son[0]&&rk<l_siz)
                    now=now->son[0];
                else
                {
                    long long temp=rk-now->cnt-l_siz;
                    if(temp<0)
                    {
                        splay(now,goal);
                        return now;
                    }
                    rk-=now->cnt+l_siz;
                    now=now->son[1];
                }
            }
        }
    public:
        size_t size()
        {
            return root==nullptr?0ULL:root->size;
        }
    private:
        node* get_range(size_t l,size_t r)
        {
            if(l==0ULL&&r==size())
                return root;
            if(l==0ULL)
                return find_by_rank_base(r)->son[0];
            if(r==size())
                return find_by_rank_base(l-1ULL)->son[1];
            find_by_rank_base(l-1ULL);
            return find_by_rank_base(r,find_by_rank_base(l-1ULL))->son[0];
        }
        void traversal(node* now,std::vector<T>& arr)
        {
            if(now==nullptr)
                return;
            now->lzd_down();
            traversal(now->son[0],arr);
            arr.push_back(now->val);
            traversal(now->son[1],arr);
        }
    public:
        rope_based_on_splay():root(nullptr){}
        rope_based_on_splay(const std::vector<T>& arr):root(nullptr)
        {
            for(const T& val:arr)
            {
                node* temp=new node(val);
                if(root==nullptr)
                    root=temp;
                else
                {
                    temp->son[0]=root;
                    root->fa=temp;
                    temp->recalc_size();
                    root=temp;
                }
            }
        }
        ~rope_based_on_splay(){destroy(root);}
        void clear()
        {
            destroy(root);
            root=nullptr;
        }
        void reverse(size_t l,size_t len)
        {
            get_range(l,l+len)->reverse();
        }
        const std::vector<T> get_arr()
        {
            std::vector<T>arr;
            arr.reserve(size());
            traversal(root,arr);
            return arr;
        }
};
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    std::vector<int>arr(n);
    for(int i=1;i<=n;i++)
        arr[i-1]=i;
    rope_based_on_splay<int>bst(arr);
    while(m--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        bst.reverse(a,b-a+1);
    }
    arr=bst.get_arr();
    for(size_t i=0;i<arr.size();i++)
        printf("%d ",arr[i]);
    return 0;
}
2024/4/11 16:14
加载中...