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

    单点插入删除以及求前缀
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M=100055,inf=1000000000;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n,m,root;
    int c[M][2],size[M],fa[M],v[M],pos[M];
    void up(int k){size[k]=size[c[k][0]]+size[c[k][1]]+1;}
    void rotate(int x,int& k){
        int y=fa[x],z=fa[y],l=0,r=1;
        if(c[y][1]==x) l=1,r=0;
        if(y==k) k=x;
        else{if(c[z][0]==y) c[z][0]=x; else c[z][1]=x;}
        fa[y]=x; fa[x]=z; fa[c[x][r]]=y;
        c[y][l]=c[x][r]; c[x][r]=y;
        up(y); up(x);
    }
    void splay(int x,int& k){
        while(x!=k){
            int y=fa[x],z=fa[y];
            if(y!=k){
                if(c[z][0]==y^c[y][0]==x) rotate(y,k);
                else rotate(x,k);
            }
            rotate(x,k);
        }
    }
    int find(int x,int rank){
        int l=c[x][0],r=c[x][1];
        if(size[l]+1==rank) return x;
        else if(size[l]>=rank) return find(l,rank);
        else return find(r,rank-size[l]-1);
    }
    int build(int l,int r){
        if(l>r) return 0;
        int m=(l+r)>>1;
        c[m][0]=build(l,m-1);
        c[m][1]=build(m+1,r);
        for(int i=0;i<2;i++) if(c[m][i]) fa[c[m][i]]=m;
        up(m); return m;
    }
    void del(int k){
        int x,y,z;
        x=find(root,k-1); y=find(root,k+1);
        splay(x,root); splay(y,c[x][1]);
        z=c[y][0]; c[y][0]=0; size[z]=fa[z]=0;
        up(y); up(x);
    }
    void move(int k,int w){
        int x,y,z=pos[k],rank;
        splay(z,root); rank=size[c[z][0]]+1;
        del(rank);
        if(w==-inf) x=find(root,1),y=find(root,2);
        else if(w==inf) x=find(root,n),y=find(root,n+1);
        else x=find(root,rank+w-1),y=find(root,rank+w);
        splay(x,root); splay(y,c[x][1]);
        size[z]=1; fa[z]=y; c[y][0]=z;
        up(y); up(x);
    }
    int main()
    {
        int k,T;
        n=read(); m=read();
        for(int i=2;i<=n+1;i++) v[i]=read(),pos[v[i]]=i;
        root=build(1,n+2);
        char ch[15];
        while(m--){
            scanf("%s",ch); k=read();
            if(ch[0]=='T') move(k,-inf);
            if(ch[0]=='B') move(k,inf);
            if(ch[0]=='I') T=read(),move(k,T);
            if(ch[0]=='A') splay(pos[k],root),printf("%d
    ",size[c[pos[k]][0]]-1);
            if(ch[0]=='Q') T=find(root,k+1),printf("%d
    ",v[T]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    通讯录封装实现
    简单通讯录的实现 main..h .m文件全部
    iOS 开发 OC编程 字典和集合 排序方法
    iOS 开发 OC编程 数组冒泡排序.图书管理
    iOS 开发 OC编程 属性和字符串练习
    iOS 开发 OC编程 属性和字符串
    iOS 开发 OC编程 便利构造器以及初始化方法
    iOS 开发 OC编程 方法的书写
    IOS 开发 OC编程 类和对象
    iOS 开发 c语言阶段考试题
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/6922426.html
Copyright © 2011-2022 走看看