• [洛谷P3391]【模板】文艺平衡树(Splay)


    题目大意:给定一个$1sim n$的序列,每次翻转一个区间,输出最后的序列。

    解题思路:Splay的区间翻转操作。我借此打了个Splay的模板(运用内存池,但有些功能不确定正确,例如单点插入)。

    大致思路就是,每次找到$l−1$和$r+1$两个节点,把$l−1$旋转到根,$r+1$旋转到根的右子树,则根的右子树的左子树就是$l,r$的区间。

    对于翻转一个区间,直接打上标记,访问到这个节点时,下传标记并交换两个儿子节点。

    注意访问$l−1$,$r+1$时可能访问到$0$和$n+1$,所以要多开两个节点。

    最后输出即可。

    C++ Code:

    #include<bits/stdc++.h>
    inline int readint(){
        char c=getchar();
        for(;!isdigit(c);c=getchar());
        int d=0;
        for(;isdigit(c);c=getchar())
        d=(d<<3)+(d<<1)+(c^'0');
        return d;
    }
    int n;
    template<typename T>
    class Splay{
        private:
            struct node{
                T value;
                int sz;
                bool rotag;
                node *fa,*ch[2];
            };
        public:
            node* rt;
            int n;
        private:
            node a[1000000],*stk[1000000];
            int top;
            inline void pushdown(node* t){
                if(t->rotag){
                    node* x=t->ch[0];
                    t->ch[0]=t->ch[1];
                    t->ch[1]=x;
                    if(t->ch[0]!=NULL)
                    t->ch[0]->rotag^=1;
                    if(t->ch[1]!=NULL)
                    t->ch[1]->rotag^=1;
                    t->rotag=0;
                }
            }
            inline node* newnode(T v,node* f){
                node* now=stk[--top];
                now->sz=1;
                now->value=v;
                now->fa=f;
                now->ch[0]=now->ch[1]=NULL;
                now->rotag=false;
                return now;
            }
            inline void dispose(node*&t){stk[top++]=t;t=NULL;}
            inline int findson(node* f,node* s){
                return(f->ch[1]==s)?1:0;
            }
            inline void update(node* t){
                t->sz=1;
                if(t->ch[0]!=NULL)t->sz+=t->ch[0]->sz;
                if(t->ch[1]!=NULL)t->sz+=t->ch[1]->sz;
            }
            inline void rotate(node* t){
                node* f=t->fa;
                node* g=f->fa;
                int a=findson(f,t),b=a^1;
                if(t->ch[b]!=NULL)t->ch[b]->fa=f;
                f->ch[a]=t->ch[b];
                t->ch[b]=f;
                f->fa=t;
                t->fa=g;
                if(g!=NULL)g->ch[findson(g,f)]=t;else
                rt=t;
                update(f);
                update(t);
            }
        public:
            Splay(){
                for(int i=0;i<1000000;++i)stk[i]=&a[i];
                top=1000000;
            }
            inline void splay(node* t,node* p){
                if(t==NULL)return;
                pushdown(t);
                while(t->fa!=p){
                    node* f=t->fa;
                    node* g=f->fa;
                    if(g==p)rotate(t);else
                    if(findson(g,f)!=findson(f,t))
                    rotate(t),rotate(t);else
                    rotate(f),rotate(t);
                }
            }
            inline node* find(node* now,int y){
                while(now!=NULL){
                    pushdown(now);
                    int t;
                    if(now->ch[0]==NULL)t=1;else
                    t=now->ch[0]->sz+1;
                    if(t==y)return now;
                    if(t<y)y-=t,now=now->ch[1];else
                    now=now->ch[0];
                }
            }
            inline void build(node*& p,int l,int r,node* f=NULL){
                if(l>r)return;
                int mid=l+r>>1;
                p=newnode(mid,f);
                build(p->ch[0],l,mid-1,p);
                build(p->ch[1],mid+1,r,p);
                update(p);
            }
            inline void insert(T val){
                if(rt==NULL)rt=newnode(val,NULL);
                int x;
                for(node* t=rt;t;t=t->son[x]){
                    x=val>=t->value?1:0;
                    if(t->ch[x]==NULL){t->son[x]=newnode(val,t);splay(t->son[x],rt);break;}
                }
            }
            inline void rev(node* p,int l,int r){
                node* pre=find(p,l),*suc=find(p,r);
                splay(pre,NULL);
                splay(suc,rt);
                if(rt->ch[1]->ch[0]!=NULL)
                rt->ch[1]->ch[0]->rotag^=1;
            }
            inline void print(node* p){
                if(p==NULL)return;
                pushdown(p);
                print(p->ch[0]);
                if(p->value>1&&p->value<n+2)printf("%d ",p->value-1);
                print(p->ch[1]);
            }
            inline void build(int nn){
                n=nn;
                build(rt,1,n+2);
            }
    };
    Splay<int>Tree;
    int main(){
        n=readint();int m=readint();
        Tree.build(n);
        while(m--){
            int l=readint(),r=readint();
            Tree.rev(Tree.rt,l,r+2);
        }
        Tree.print(Tree.rt);
        return 0;
    }
    
  • 相关阅读:
    Dictionaries and lists
    Looping and dictionaries
    Dictionary as a set of counters
    Dictionaries
    List exercise
    Lists and strings
    Copying lists
    Objects and values
    [luoguP1944] 最长括号匹配_NOI导刊2009提高(1)
    [luoguP1868] 饥饿的奶牛(DP)
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/8535905.html
Copyright © 2020-2023  润新知