• ZJOI2006 书架


    一道平衡树裸题,但要注意细节。pos数组定位该元素的权重。

    #include<bits/stdc++.h>
    #define N 80009
    using namespace std;
    #define sight(c) ('0'<=c&&c<='9')
    #define RR NULL
    #define dwl  writel 
    inline void read(int &x){
        static char c;static int b;
        for (b=1,c=getchar();!sight(c);c=getchar())if (c=='-') b=-1;
        for (x=0;sight(c);c=getchar())x=x*10+c-48;x*=b;
    }
    void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
    inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('
    '); }
    inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
    struct Node{
        int val,key;
        Node() {}
        Node(int V,int K):val(V),key(K){}
        inline bool operator <(const Node& A)const{ return val<A.val;}
    };
    inline int rod() {
        static int x=23333;
        return x^=x<<13,x^=x>>17,x^=x<<5;
    }
    struct Treap{
        Node key;int val,siz;Treap* son[2];
        Treap() { val=rod(); siz=1; son[0]=son[1]=RR;}
        Treap(int V,int K) {
            key.key=K; key.val=V; val=rod(); siz=1; son[0]=son[1]=RR;
        }
        inline void rob(){
            siz=1;
            if (son[0]) siz+=son[0]->siz;
            if (son[1]) siz+=son[1]->siz;
        }
        inline int ask(){
            return son[0]?son[0]->siz+1:1;
        }
    };
    int find(int x,Treap *now){
        if (!now) return 0;
        if (now->key.val<x) return now->ask()+find(x,now->son[1]);
        return find(x,now->son[0]);
    }
    void spilt(Treap *now,int k,Treap *&x,Treap *&y){
        if (!now) {x=y=RR;return;}
        int cmp=now->ask();
        if (k>=cmp) x=now,spilt(x->son[1],k-cmp,x->son[1],y); 
        else  y=now,spilt(y->son[0],k,x,y->son[0]);
        now->rob();
    }
    Treap* merge(Treap *x,Treap *y){
        if (!x) return y; if (!y) return x;
        if (x->val<y->val) {x->son[1]=merge(x->son[1],y);x->rob();return x;}
        y->son[0]=merge(x,y->son[0]); y->rob(); return y;
    }
    void dfs(Treap* x){
        if (!x) return;
        if (x->son[0]) dfs(x->son[0]);
        dwl(x->key.key);
        if (x->son[1]) dfs(x->son[1]);
        x->rob();
    }
    int n,m,pos[N],a[N],x,l,r,k,op;
    char ch[1707];
    #define Mid (l+r>>1)
    void build (Treap* &now,int l,int r){
        if (l>r) return;
        now=new Treap(Mid,a[Mid]);
        build(now->son[0],l,Mid-1); build(now->son[1],Mid+1,r);
        now->rob();
    }
    Treap *root,*xr,*yr,*zr,*tr;
    int main () {
    //   freopen("a.in","r",stdin);
    //   freopen("a.out","w",stdout);
       read(n); read(m);
    //   for (int i=1;i<=n;i++)
    //    read(a[i]),pos[a[i]]=i;
    //   build(root,1,n);
       for(int i=1;i<=n;i++) {
            read(x); pos[x]=i; 
         root=merge(root,new Treap(i,x));
       } 
    //   dfs(root); putchar('
    ');
       l=1; r=n;
       while (m--) {
            scanf("%s",ch);
            switch (ch[0]) {
                 case 'T':
                     read(x); k=find(pos[x],root);
                     spilt(root,k,xr,yr); spilt(yr,1,tr,yr);
                     pos[x]=--l; root=merge(new Treap(pos[x],x),merge(xr,yr));
                     break;
                 case 'B':
                     read(x); k=find(pos[x],root);
                     spilt(root,k,xr,yr); spilt(yr,1,tr,yr);
                     pos[x]=++r; root=merge(merge(xr,yr),new Treap(pos[x],x));
                    break;
                 case 'I':
                     read(x); read(op);
                     if (op==1) {
                         k=find(pos[x],root);
                         spilt(root,k,xr,yr); spilt(yr,2,tr,yr); spilt(tr,1,tr,zr);
                         swap(pos[tr->key.key],pos[zr->key.key]);
                         swap(tr->key.val,zr->key.val);
                         root=merge(merge(xr,zr),merge(tr,yr));    
                     }
                if (op==-1) {
                    k=find(pos[x],root);
                         spilt(root,k-1,xr,yr); spilt(yr,2,tr,yr); spilt(tr,1,tr,zr);
                         swap(pos[tr->key.key],pos[zr->key.key]);
                         swap(tr->key.val,zr->key.val);
                    root=merge(merge(xr,zr),merge(tr,yr));
                }
                      break;
                 case 'A':
                     read(x); writeln(find(pos[x],root));
                     break;
                 case 'Q':
                     read(k); spilt(root,k-1,xr,yr); spilt(yr,1,yr,zr);
                     writeln(yr->key.key);
                     root=merge(merge(xr,yr),zr);
                     break;
           } 
       } return 0;
    }
  • 相关阅读:
    随笔35 内联函数
    随笔32 内部类,外部类,局部内部类
    随笔31 Spring的依赖注入的三种方式
    随笔30 抽象类与接口
    随笔29 Statement对象
    随笔28 Spring中的事务
    随笔27 面向对象的五大基本原则
    随笔26 java中的泛型
    html5学习笔记——HTML5 web存储
    html5学习笔记——HTML 5 视频
  • 原文地址:https://www.cnblogs.com/gaozeke/p/8335991.html
Copyright © 2020-2023  润新知