zoukankan      html  css  js  c++  java
  • 【BZOJ 3223】文艺平衡树 模板题

      就是打个翻转标记,下推标记时记得交换左右孩子指针,查询kth和中序遍历输出时也记得要下推标记同时交换指针,二者不可缺!←这是易错点

    仿陈竞潇学长模板的代码:

    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct node{
        node();
        node *ch[2],*fa;
        short reversal;
        short pl(){return this==fa->ch[1];}
        int d,sum;
        void push(); void count();
    }*null;
    int N,M;
    node::node(){ch[0]=ch[1]=fa=null;reversal=sum=d=0;}
    void node::push(){
        if (this==null) return;
        if (reversal==1){
            reversal=0;
            ch[0]->reversal^=1;
            ch[1]->reversal^=1;
            node *k=ch[0];
            ch[0]=ch[1];
            ch[1]=k;
        }
    }
    void node::count(){
        sum=ch[0]->sum+ch[1]->sum+1;
    }
    namespace Splay{
        node *ROOT;
        node *build(int l=1,int r=N){
            if (l>r) return null;
            int mid=(l+r)>>1;
            node *ro=new node;
            ro->d=mid;
            ro->ch[0]=build(l,mid-1);
            ro->ch[1]=build(mid+1,r);
            ro->ch[0]->fa=ro;
            ro->ch[1]->fa=ro;
            ro->count();
            return ro;
        }
        void Build(){
            null=new node;
            *null=node();
            ROOT=build();
            ROOT->count();
        }
        void rotate(node *k){
            node *r=k->fa; if (r==null||k==null) return;
            r->push(); k->push();
            int x=k->pl()^1;
            r->ch[x^1]=k->ch[x];
            r->ch[x^1]->fa=r;
            if (r->fa==null) ROOT=k;
            else r->fa->ch[r->pl()]=k;
            k->fa=r->fa;
            r->fa=k;
            k->ch[x]=r;
            r->count(); k->count();
        }
        void splay(node *r,node *tar=null){
            for (;r->fa!=tar;rotate(r))
             if (r->fa->fa!=tar)rotate(r->pl()==r->fa->pl()?r->fa:r);
            r->push();
        }
        node *kth(int x){
            node *r=ROOT;
            while (r!=null){
                r->push();
                if (r->ch[0]->sum>=x) r=r->ch[0];
                else if (r->ch[0]->sum+1>=x) return r;
                else x-=r->ch[0]->sum+1,r=r->ch[1];
            }return null;
        }
        void rollingover(int ll,int rr){
            node *ln=kth(ll-1),*rn=kth(rr+1),*r;
            if ((ln==null)&&(rn==null)) r=ROOT;
            else if (ln==null){
                splay(rn); r=ROOT->ch[0];
            }else if (rn==null){
                splay(ln); r=ROOT->ch[1];
            }else{
                splay(ln); splay(rn,ROOT);
                r=ROOT->ch[1]->ch[0];
            }r->reversal=r->reversal^1;
        }
        void AC(node *r=ROOT){
            if (r==null) return;
            r->push();
            AC(r->ch[0]);
            printf("%d ",r->d);
            AC(r->ch[1]);
        }
    }
    int getint()
    {
        char c;
        while (!isdigit(c=getchar()));
        int a=c-'0';
        while (isdigit(c=getchar()))
         a=a*10+c-'0';
        return a;
    }
    int main()
    {
        N=getint();M=getint();
        Splay::Build();
        while (M--){
            int l=getint(),r=getint();
            Splay::rollingover(l,r);
        }
        Splay::AC();
        return 0;
    }
    

    自己写的62行简洁代码:

    #include<cstdio>
    #include<algorithm>
    #define read(x) x=getint()
    using namespace std;
    inline int getint(){char c;int ret=0;for(c=getchar();c<'0'||c>'9';c=getchar());for(;c>='0'&&c<='9';c=getchar())ret=ret*10+c-'0';return ret;}
    struct node{
    	node();
    	node *fa,*ch[2];
    	int d,sum;
    	bool rev;
    	bool pl() {return this->fa->ch[1]==this;}
    	void setc(node *r,bool c) {r->fa=this; this->ch[c]=r;}
    	void push() {if (rev){swap(ch[0],ch[1]);ch[0]->rev^=1;ch[1]->rev^=1;rev=0;}}
    	void count() {sum=ch[0]->sum+ch[1]->sum+1;}
    }*ROOT,*null;
    node::node(){fa=ch[0]=ch[1]=null;d=sum=rev=0;}
    int n,m;
    inline node *build(int l,int r){
    	if (l>r) return null; int mid=(l+r)>>1;	node *k=new node;
    	k->ch[0]=build(l,mid-1); k->ch[1]=build(mid+1,r);
    	if (k->ch[0]!=null) k->ch[0]->fa=k; if (k->ch[1]!=null) k->ch[1]->fa=k;
    	k->d=mid; k->count(); return k;
    }
    inline void Build() {null=new node;*null=node();ROOT=build(1,n);}
    inline void rotate(node *r){
    	node *f=r->fa; bool c=r->pl();
    	if (f!=ROOT) f->fa->setc(r,f->pl());
    	else r->fa=null,ROOT=r;
    	f->setc(r->ch[!c],c); r->setc(f,!c);
    	f->count();
    }
    inline void update(node *r) {if (r!=null) update(r->fa); r->push();}
    inline void splay(node *r,node *tar=null){
    	update(r);
    	for(;r->fa!=tar;rotate(r)) if (r->fa->fa!=tar) rotate(r->fa->pl()==r->pl()?r->fa:r);
    	r->count();
    }
    inline node *kth(int x){
    	if ((x==0)||(x==n+1)) return null;
    	node *r=ROOT;
    	while (1){
    		r->push();
    		if (r->ch[0]->sum>=x) r=r->ch[0];
    		else if (r->ch[0]->sum+1>=x) return r;
    		else {x-=r->ch[0]->sum+1; r=r->ch[1];}
    	}
    }
    inline void reversal(int l,int r){
    	node *ll=kth(l-1),*rr=kth(r+1);
    	if ((ll==null)&&(rr==null)) ROOT->rev^=1;
    	else if (ll==null) splay(rr),ROOT->ch[0]->rev^=1;
    	else if (rr==null) splay(ll),ROOT->ch[1]->rev^=1;
    	else splay(ll),splay(rr,ROOT),rr->ch[0]->rev^=1;
    }
    inline void AC(node *r) {if (r==null) return; r->push(); AC(r->ch[0]); printf("%d ",r->d); AC(r->ch[1]);}
    int main(){
    	read(n); read(m); Build();
    	int l,r;
    	while (m--) {read(l); read(r); reversal(l,r);}
    	AC(ROOT);
    	return 0;
    }
    

    然后就可以了

  • 相关阅读:
    Python的单元测试(二)
    Python的单元测试(一)
    未知道——广场式的真匿名交流网站(一)
    xpath提取多个标签下的text
    清空Github上某个文件的历史版本
    如何正确使用日志Log
    使用AWS亚马逊云搭建Gmail转发服务(三)
    玩转Windows服务系列——Windows服务小技巧
    玩转Windows服务系列——服务运行、停止流程浅析
    玩转Windows服务系列——无COM接口Windows服务启动失败原因及解决方案
  • 原文地址:https://www.cnblogs.com/abclzr/p/5195557.html
Copyright © 2011-2022 走看看