zoukankan      html  css  js  c++  java
  • bzoj1861:[Zjoi2006]Book 书架

    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
     
    题解:
    基本上是splay模板题吧……
    操作都很容易实现,就是需要记录一下编号为x的书在splay的什么位置
    这块我想了好久才想明白,不管这个点位置怎么变它在splay中始终是这个点,所以只在插入点时记录一下就好了(pos数组)
    比最普通的模板多了一个Get_Rank,用来求这个点是splay中的第几个点:先加上这个点左子的size,然后不断往上走,若是parent的右子则需要加上parent左子的size+1
     
    代码:
      1 #include<cstdio>
      2 #include<iostream>
      3 using namespace std;
      4 
      5 const int MAXN=80005;
      6 struct node
      7 {
      8     int d,size;
      9     node *parent,*ch[2];
     10 }pool[MAXN],*root,*rf,*tmp;
     11 int cnt,pos[MAXN];
     12 int size(node *p)
     13 {
     14     if(p) return p->size;
     15     return 0;    
     16 }
     17 void update(node *p)
     18 {
     19     p->size=1+size(p->ch[0])+size(p->ch[1]);     
     20 }
     21 void rotate(node *p,int type)
     22 {
     23     node *parent=p->parent,*son=p->ch[!type],*gp=p->parent->parent;
     24     parent->ch[type]=son;
     25     if(son) son->parent=parent;
     26     p->ch[!type]=parent;
     27     parent->parent=p;
     28     p->parent=gp;
     29     gp->ch[parent==gp->ch[1]]=p;
     30     update(parent);
     31     update(p);
     32     if(parent==root) root=p;
     33 }
     34 void splay(node *p,node *target)
     35 {
     36     while(p->parent!=target)
     37     {
     38         if(p->parent->parent==target)
     39             rotate(p,p==p->parent->ch[1]);
     40         else
     41         {
     42             node *parent=p->parent,*gp=p->parent->parent;
     43             int f=parent==gp->ch[0];
     44             if(p==parent->ch[f]) rotate(p,f),rotate(p,!f);
     45             else rotate(parent,!f),rotate(p,!f);    
     46         }
     47     } 
     48 }
     49 node *find(node *p,int k)
     50 {
     51     if(size(p->ch[0])>=k) return find(p->ch[0],k);
     52     else if(size(p->ch[0])==k-1) return p;
     53     else return find(p->ch[1],k-1-size(p->ch[0]));     
     54 }
     55 void insert(int x,node *newnode)
     56 {
     57     node *p=find(root,x);
     58     splay(p,rf);
     59     p=find(root,x+1);
     60     splay(p,root);
     61     p->ch[0]=newnode;
     62     newnode->parent=p;
     63     update(p);
     64     update(p->parent); 
     65 }
     66 void del(int x)
     67 {
     68     node *p=find(root,x-1);
     69     splay(p,rf);
     70     p=find(root,x+1);
     71     splay(p,root);
     72     p->ch[0]=NULL;
     73     update(p);
     74     update(p->parent);  
     75 }
     76 int Get_Rank(node *p)
     77 {
     78     int ret=size(p->ch[0]);
     79     while(p!=root)
     80     {
     81         if(p==p->parent->ch[1]) ret+=1+size(p->parent->ch[0]);
     82         p=p->parent;
     83     }
     84     return ret+1;
     85 }
     86 
     87 int main()
     88 {
     89     int n,m,i,x,y,k,a;
     90     char ch[10];
     91     scanf("%d%d",&n,&m);
     92     
     93     rf=&pool[++cnt];
     94     root=&pool[++cnt];
     95     root->d=0;root->size=1;
     96     root->parent=rf;rf->ch[0]=root;
     97     for(i=1;i<=n;i++)
     98     {
     99         scanf("%d",&a);
    100         pos[a]=++cnt;
    101         tmp=&pool[pos[a]];
    102         tmp->d=a;tmp->size=1;
    103         tmp->parent=root;root->ch[1]=tmp;
    104         splay(tmp,rf);
    105     }
    106     tmp=&pool[++cnt];
    107     tmp->d=0;tmp->size=1;
    108     tmp->parent=root;root->ch[1]=tmp;
    109     splay(tmp,rf);
    110     
    111     while(m --> 0)
    112     {
    113         scanf("%s",ch);
    114         if(ch[0]=='T')
    115         {
    116             scanf("%d",&x);
    117             tmp=&pool[pos[x]];
    118             del(Get_Rank(tmp));
    119             insert(1,tmp);
    120         }
    121         else if(ch[0]=='B')
    122         {
    123             scanf("%d",&x);
    124             tmp=&pool[pos[x]];
    125             del(Get_Rank(tmp));
    126             insert(n,tmp);   
    127         }
    128         else if(ch[0]=='I')
    129         {
    130             scanf("%d%d",&x,&y);
    131             tmp=&pool[pos[x]];
    132             k=Get_Rank(tmp);
    133             del(k);
    134             insert(k-1+y,tmp);
    135         }
    136         else if(ch[0]=='A')
    137         {
    138             scanf("%d",&x);
    139             tmp=&pool[pos[x]];
    140             printf("%d
    ",Get_Rank(tmp)-2);     
    141         }
    142         else
    143         {
    144             scanf("%d",&x);x++;
    145             printf("%d
    ",find(root,x)->d);
    146         }
    147     } 
    148     
    149     return 0;
    150 }
    View Code
    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    Oracle性能调整ASH,AWR,ADDM
    子网掩码、子网划分详解
    10046事件sql_trace跟踪
    find详解
    date详解
    touch详解
    [转]lsof详解
    iftop、ifstat详解
    iotop详解
    关于Unity的入门游戏飞机大战的开发(上)
  • 原文地址:https://www.cnblogs.com/lindalee/p/6963312.html
Copyright © 2011-2022 走看看