• BZOJ 1861: [Zjoi2006]Book 书架


    1861: [Zjoi2006]Book 书架

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 1291  Solved: 741
    [Submit][Status][Discuss]

    Description

    小T有一个很大的书柜。这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列。她用1到n的正整数给每本书都编了号。 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本。由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置。不过小T的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时的位置附近,比如说她拿的时候这本书上面有X本书,那么放回去时这本书上面就只可能有X-1、X或X+1本书。 当然也有特殊情况,比如在看书的时候突然电话响了或者有朋友来访。这时候粗心的小T会随手把书放在书柜里所有书的最上面或者最下面,然后转身离开。 久而久之,小T的书柜里的书的顺序就会越来越乱,找到特定的编号的书就变得越来越困难。于是她想请你帮她编写一个图书管理程序,处理她看书时的一些操作,以及回答她的两个提问:(1)编号为X的书在书柜的什么位置;(2)从上到下第i本书的编号是多少。

    Input

    第一行有两个数n,m,分别表示书的个数以及命令的条数;第二行为n个正整数:第i个数表示初始时从上至下第i个位置放置的书的编号;第三行到m+2行,每行一条命令。命令有5种形式: 1. Top S——表示把编号为S的书房在最上面。 2. Bottom S——表示把编号为S的书房在最下面。 3. Insert S T——T∈{-1,0,1},若编号为S的书上面有X本书,则这条命令表示把这本书放回去后它的上面有X+T本书; 4. Ask S——询问编号为S的书的上面目前有多少本书。 5. Query S——询问从上面数起的第S本书的编号。

    Output

    对于每一条Ask或Query语句你应该输出一行,一个数,代表询问的答案。

    Sample Input

    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

    Sample Output

    2
    9
    9
    7
    5
    3

    HINT

    数据范围


    100%的数据,n,m < = 80000

     

     

    Source

    分析:

    其实就是裸题,对Splay还不是很熟练QAQ

    代码:

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 //by NeighThorn
      6 using namespace std;
      7 
      8 const int maxn=80000+5;
      9 
     10 int n,m,Min,Max,flag;
     11 int root,w[maxn],ls[maxn],rs[maxn],fa[maxn],siz[maxn];
     12 
     13 char opt[10+5];
     14 
     15 inline void zig(int x){
     16     int y=fa[x],tmp=siz[y];
     17     if(rs[x])
     18         ls[y]=rs[x],fa[rs[x]]=y,siz[y]=siz[y]-siz[x]+siz[rs[x]],siz[x]=tmp;
     19     else 
     20         ls[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
     21     fa[x]=fa[y];
     22     if(fa[x]){
     23         if(ls[fa[x]]==y)
     24             ls[fa[x]]=x;
     25         else
     26             rs[fa[x]]=x;
     27     }
     28     fa[y]=x,rs[x]=y;
     29 }
     30 
     31 inline void zag(int x){
     32     int y=fa[x],tmp=siz[y];
     33     if(ls[x])
     34         rs[y]=ls[x],fa[ls[x]]=y,siz[y]=siz[y]-siz[x]+siz[ls[x]],siz[x]=tmp;
     35     else
     36         rs[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
     37     fa[x]=fa[y];
     38     if(fa[x]){
     39         if(ls[fa[x]]==y)
     40             ls[fa[x]]=x;
     41         else
     42             rs[fa[x]]=x;
     43     }
     44     fa[y]=x,ls[x]=y;
     45 }
     46 
     47 inline void splay(int x,int z){
     48     while(fa[x]!=z){
     49         int y=fa[x];
     50         if(fa[y]==z){
     51             if(ls[y]==x)
     52                 zig(x);
     53             else
     54                 zag(x);
     55         }
     56         else{
     57             if(ls[fa[y]]==y){
     58                 if(ls[y]==x)
     59                     zig(y),zig(x);
     60                 else
     61                     zag(x),zig(x);    
     62             }
     63             else{
     64                 if(rs[y]==x)
     65                     zag(y),zag(x);
     66                 else
     67                     zig(x),zag(x);
     68             }
     69         }
     70     }
     71     if(!z)
     72         root=x;
     73 }
     74 
     75 inline void ins(int rt,int x,int id){
     76     if(!rt)
     77         w[id]=x,root=id,siz[id]=1;
     78     else if(x<w[rt]){
     79         if(ls[rt]==0)
     80             ls[rt]=id,w[id]=x,fa[id]=rt,siz[id]=1,siz[rt]++,splay(id,0);
     81         else
     82             siz[rt]++,ins(ls[rt],x,id);
     83     }
     84     else{
     85         if(rs[rt]==0)
     86             rs[rt]=id,w[id]=x,fa[id]=rt,siz[id]=1,siz[rt]++,splay(id,0);
     87         else
     88             siz[rt]++,ins(rs[rt],x,id);
     89     }
     90 }
     91 
     92 inline void del(int rt,int x){
     93     if(rt==x){
     94         splay(rt,0);
     95         int l=ls[rt],r=rs[rt];
     96         if(!l)
     97             fa[rt]=ls[rt]=rs[rt]=siz[rt]=0,fa[r]=0,root=r;
     98         else{
     99             while(rs[l])
    100                 l=rs[l];
    101             splay(l,x),fa[rt]=ls[rt]=rs[rt]=siz[rt]=0,fa[r]=l,rs[l]=r,root=l,fa[l]=0,siz[l]+=siz[r];
    102         }
    103     }
    104     else if(w[x]<w[rt])
    105         del(ls[rt],x);
    106     else
    107         del(rs[rt],x);
    108 }
    109 
    110 inline int rank(int rt,int x){
    111     if(rt==x){
    112         splay(rt,0);
    113         return siz[ls[rt]]+1;
    114     }
    115     else if(w[x]<w[rt])
    116         return rank(ls[rt],x);
    117     else
    118         return rank(rs[rt],x);
    119 }
    120 
    121 inline int query(int rt,int x){
    122     if(!ls[rt]){
    123         if(x==1){
    124             splay(rt,0);
    125             return rt;
    126         }
    127         else
    128             return query(rs[rt],x-1);
    129     }
    130     else if(siz[ls[rt]]+1==x){
    131         splay(rt,0);
    132         return rt;
    133     }
    134     else if(siz[ls[rt]]>=x)
    135         return query(ls[rt],x);
    136     else
    137         return query(rs[rt],x-siz[ls[rt]]-1);
    138 }
    139 
    140 signed main(void){
    141 flag=0;
    142     memset(ls,0,sizeof(ls));
    143     memset(rs,0,sizeof(rs));
    144     memset(fa,0,sizeof(fa));
    145     memset(siz,0,sizeof(siz));
    146     scanf("%d%d",&n,&m);root=0;Min=1,Max=n;
    147     for(int i=1,x;i<=n;i++)
    148         scanf("%d",&x),ins(root,i,x);
    149     for(int i=1,x,y;i<=m;i++){
    150         scanf("%s%d",opt,&x);
    151         if(opt[0]=='T')
    152             Min--,del(root,x),ins(root,Min,x);
    153         else if(opt[0]=='B')
    154             Max++,del(root,x),ins(root,Max,x);
    155         else if(opt[0]=='I'){
    156             scanf("%d",&y);splay(x,0);
    157             if(y==-1){
    158                 int l=ls[x];
    159                 while(rs[l])
    160                     l=rs[l];
    161                 splay(l,x);int a=w[x],b=w[l];del(root,x),del(root,l);ins(root,b,x),ins(root,a,l);
    162             }
    163             else if(y==1){
    164                 int r=rs[x];
    165                 while(ls[r])
    166                     r=ls[r];
    167                 splay(r,x);int a=w[x],b=w[r];del(root,x),del(root,r);ins(root,b,x),ins(root,a,r);
    168             }
    169         }
    170         else if(opt[0]=='A')
    171             printf("%d
    ",rank(root,x)-1);
    172         else
    173             printf("%d
    ",query(root,x));
    174     }
    175     return 0;
    176 }
    View Code

    by NeighThorn

  • 相关阅读:
    洛谷1052——过河(DP+状态压缩)
    mod4最优路径问题(转载)
    初次接触python,怎么样系统的自学呢?
    对AM信号FFT的matlab仿真
    初次使用自己写的testbench 验证了简单的NOT门。
    写简单的tb(testbench)文件来测试之前的FSM控制的LED
    利用简单的有限状态机(FSM)来实现一个简单的LED流水灯
    利用状态机(FSM)进行简单的uart串口发送数据
    用matlab脚本语言写M文件函数时用三种方法简单实现实现DFT(离散傅里叶变换)
    作为新手对于初次接触matlab的一些感受。
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6154873.html
Copyright © 2020-2023  润新知