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

    追yql做题记录的时候做到的……一道Splay模版题……

    啊LCT写久了都有点忘了Splay了(什么奇怪的逻辑?)

    其实说白了五个操作:

    1、 将某元素置顶:将元素旋到根,然后将左子树合并到该元素的后继

    2、 将某元素置底:将元素旋到根,然后将右子树合并到该元素的前驱

    3、 将某元素提前/滞后1位:直接与该元素的前驱/后继交换位置及信息

    4、 询问指定元素排名:将元素旋到根,输出size-1

    5、 询问指定排名元素:在树上find

    不好,我……我发现……我还在写数据结构!

     1 #include<bits/stdc++.h>
     2 #define N 80005
     3 #define inf 1000000007
     4 using namespace std;
     5 int n,m,a[N],sz,pos[N];
     6 struct Splay_Tree{
     7     int c[N][2],fa[N],dep[N],size[N],val[N],rt;
     8     inline void pushup(int x){size[x]=size[c[x][0]]+size[c[x][1]]+1;}
     9     inline void rotate(int x,int &k){
    10         int y=fa[x],z=fa[y],l,r;
    11         if(c[y][0]==x)l=0;else l=1;r=l^1;
    12         if(y==k)k=x;
    13         else {if(c[z][0]==y)c[z][0]=x;else c[z][1]=x;}
    14         fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
    15         c[y][l]=c[x][r];c[x][r]=y;
    16         pushup(y);pushup(x);
    17     }
    18     inline void splay(int x,int &k){
    19         while(k!=x){
    20             int y=fa[x],z=fa[y];
    21             if(y!=k){
    22                 if((c[z][0]==y)^(c[y][0]==x))rotate(x,k);
    23                 else rotate(y,k);
    24             }rotate(x,k);
    25         }
    26     }
    27     void build(int l,int r,int f){
    28         if(l>r)return;
    29         int now=l,last=f;
    30         if(l==r){
    31             val[l]=a[l];size[l]=1;fa[l]=f;
    32             if(l<f)c[f][0]=l;else c[f][1]=l;
    33         }
    34         int mid=(l+r)>>1;
    35         build(l,mid-1,mid);build(mid+1,r,mid);
    36         val[mid]=a[mid];fa[mid]=f;pushup(mid);
    37         if(mid<f)c[f][0]=mid;else c[f][1]=mid;
    38     }
    39     int find(int k,int x){
    40         int l=c[k][0],r=c[k][1];
    41         if(size[l]+1==x)return k;
    42         else if(size[l]>=x)return find(l,x);
    43         else return find(r,x-size[l]-1);
    44     }
    45     void del(int k){
    46         int x=find(rt,k-1),y=find(rt,k+1),z;
    47         splay(x,rt);splay(y,c[x][1]);
    48         z=c[y][0];c[y][0]=0;fa[z]=size[z]=0;
    49         pushup(y);pushup(x);
    50     }
    51     void move(int k,int v){
    52         int x,y,z=pos[k],rk;
    53         splay(z,rt);rk=size[c[z][0]]+1;
    54         del(rk);
    55         if(v==inf)x=find(rt,n),y=find(rt,n+1);
    56         else if(v==-inf)x=find(rt,1),y=find(rt,2);
    57         else x=find(rt,rk+v-1),y=find(rt,rk+v);
    58         splay(x,rt);splay(y,c[x][1]);
    59         size[z]=1;fa[z]=y;c[y][0]=z;
    60         pushup(y);pushup(x);
    61     }
    62 }Splay;
    63 inline int read(){
    64     int f=1,x=0;char ch;
    65     do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    66     do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    67     return f*x;
    68 }
    69 int main(){
    70     n=read();m=read();
    71     for(int i=2;i<=n+1;i++)a[i]=read(),pos[a[i]]=i;
    72     Splay.build(1,n+2,0);Splay.rt=(n+3)>>1;
    73     char s[20];int x,y;
    74     while(m--){
    75         scanf("%s",s);x=read();
    76         switch(s[0]){
    77         case 'T':Splay.move(x,-inf);break;
    78         case 'B':Splay.move(x,inf);break;
    79         case 'I':y=read();Splay.move(x,y);break;
    80         case 'A':Splay.splay(pos[x],Splay.rt);printf("%d
    ",Splay.size[Splay.c[pos[x]][0]]-1);break;
    81         case 'Q':printf("%d
    ",Splay.val[Splay.find(Splay.rt,x+1)]);break;
    82         }
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    FJNU 1151 Fat Brother And Geometry(胖哥与几何)
    FJNU 1157 Fat Brother’s ruozhi magic(胖哥的弱智术)
    FJNU 1159 Fat Brother’s new way(胖哥的新姿势)
    HDU 3549 Flow Problem(最大流)
    HDU 1005 Number Sequence(数列)
    Tickets(基础DP)
    免费馅饼(基础DP)
    Super Jumping! Jumping! Jumping!(基础DP)
    Ignatius and the Princess IV(基础DP)
    Keywords Search(AC自动机)
  • 原文地址:https://www.cnblogs.com/zcysky/p/6843982.html
Copyright © 2011-2022 走看看