zoukankan      html  css  js  c++  java
  • bzoj1861 书架

    bzoj1861 书架


    原题链接


    神题。。。
    先吐槽洛谷的样例

    10 10
    1 3 2 7 5 8 10 4 9 6
    Query 3
    Top 5
    Ask 6
    Bottom 3
    Ask 3
    Top 6
    Insert 4 –1
    Query 5
    Query 2
    Ask 2
    

    bzoj的样例

    10 10 
    1 3 2 7 5 8 10 4 9 6
    Query 3 
    Top 5 
    Ask 6 
    Bottom 3 
    Ask 3 
    Top 6 
    Insert 4 -1 
    Query 5 
    Query 2 
    Ask 2 
    

    区别?号与-号。。。

    于是洛谷样例被我改了!!!


    吐槽完毕

    如果你知道书在哪这就是treap裸题。
    然而不知道
    所以,要知道书在哪。
    可以一开始记录一下每个点的地址。
    地址永远不会改变对吧
    然后?一直跳father,如果他是father的rs就ans+=father的ls的size+1
    ans初值为ls的size+1
    为什么是对的?自己想
    然而treap并不能维护father,只好加一个
    updata时顺便更新

    il vd reset(){
        size=ls->size+rs->size+1;
        if(ls!=null)ls->fa=this;if(rs!=null)rs->fa=this;
    }
    

    然后?treap裸题a
    1A了

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    #define mp make_pair
    #define pr pair<point,point>
    #define fir first
    #define sec second
    typedef long long ll;
    il int gi(){
        rg int x=0;rg char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x;
    }
    const int maxn=80010;
    int A[maxn],n;
    int seed=233333;
    il int Rand(){return seed=seed*23333ll%19260817;}
    typedef struct node* point;
    point null;
    struct node{
        int num,size,rand;
        point ls,rs,fa;
        node(int _num){num=_num,size=1,rand=Rand(),ls=rs=fa=null;}
        il vd reset(){
        size=ls->size+rs->size+1;
        if(ls!=null)ls->fa=this;if(rs!=null)rs->fa=this;
        }
    };point root,pos[maxn];
    il point build(int n){
        point stk[n+1],now,lst;int top=0;
        rep(i,1,n){
        pos[A[i]]=now=new node(A[i]),lst=null;
        while(top&&stk[top]->rand>now->rand)lst=stk[top],stk[top--]->reset();
        if(top)stk[top]->rs=now;now->ls=lst,stk[++top]=now;
        }
        while(top)stk[top--]->reset();
        return stk[1];
    }
    il point merge(point a,point b){
        if(a==null)return b;
        if(b==null)return a;
        if(a->rand<b->rand){a->rs=merge(a->rs,b),a->reset();return a;}
        b->ls=merge(a,b->ls),b->reset();return b;
    }
    il pr split(point x,int num){
        if(x==null)return mp(null,null);
        point ls=x->ls,rs=x->rs;
        if(num==x->ls->size){x->ls=null,x->reset();return mp(ls,x);}
        if(num==x->ls->size+1){x->rs=null,x->reset();return mp(x,rs);}
        if(num<x->ls->size){pr t=split(x->ls,num);x->ls=t.sec;x->reset();return mp(t.fir,x);}
        pr t=split(x->rs,num-x->ls->size-1);x->rs=t.fir;x->reset();return mp(x,t.sec);
    }
    il int getpos(point x){
        int ret=x->ls->size+1;
        while(x->fa!=null){
        if(x==x->fa->rs)ret+=x->fa->ls->size+1;
        x=x->fa;
        }return ret;
    }
    int main(){
        n=gi();
        int m=gi();
        null=new node(0);
        null->size=0,null->ls=null->rs=null->fa=null;
        rep(i,1,n)A[i]=gi();
        root=build(n);
        int S,T,p;
        pr t1,t2,t3;point x;
        char opt;
        while(m--){
        do opt=getchar();while(opt<'A'||opt>'Z');
        if(opt=='T'){
            S=gi(),p=getpos(pos[S]);
            t1=split(root,p-1),t2=split(t1.sec,1);
            root=merge(t2.fir,merge(t1.fir,t2.sec));
        }
        else if(opt=='B'){
            S=gi(),p=getpos(pos[S]);
            t1=split(root,p-1),t2=split(t1.sec,1);
            root=merge(merge(t1.fir,t2.sec),t2.fir);
        }
        else if(opt=='I'){
            S=gi(),scanf("%d",&T),p=getpos(pos[S]);
            if(T==0)continue;
            if(T==1)t1=split(root,p-1);else t1=split(root,p-2);
            t2=split(t1.sec,1),t3=split(t2.sec,1);
            root=merge(merge(merge(t1.fir,t3.fir),t2.fir),t3.sec);
        }
        else if(opt=='A')S=gi(),printf("%d
    ",getpos(pos[S])-1);
        else if(opt=='Q'){
            p=gi();
            t1=split(root,p-1);
            x=t1.sec;while(x->ls!=null)x=x->ls;
            printf("%d
    ",x->num);
            root=merge(t1.fir,t1.sec);
        }
        }
        return 0;
    }
    
  • 相关阅读:
    无法加载模块 TP3.2
    always_populate_raw_post_data
    关于(void**)及其相关的理解
    面向对象设计原则
    数据对齐总结
    C++ POD类型
    do..while(false)的用法总结
    c++为什么定义了析构函数的类的operator new[]传入的参数会多4字节?
    C++ new new[]详解
    【转】C内存操作函数
  • 原文地址:https://www.cnblogs.com/xzz_233/p/7565372.html
Copyright © 2011-2022 走看看