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

    
    

    1861: [Zjoi2006]Book 书架

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 1581  Solved: 884
    [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


    id[i]
    记录编号为i的书在SPLAY中的结点编号,key[i]记录splay中的i结点的书的编号。
    splay维护书架上从上到下的书。
    TOP:把这本书找到,删掉。然后把最前面的那本书旋转到根,然后把这本书放在根的右儿子。
    Bottom类似。
    Insert:把这本书找到删掉,然后在相应的位置插入即可。
    Ask:旋转到根,查询左儿子的size即可。
    Query:用size查找即可。
    还有数组要开两倍以上,因为有很多新加结点的操作。
    感觉很复杂,调废我。

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 #define maxn 200010
      8 using namespace std;
      9 int ch[maxn][2],pre[maxn],size[maxn],key[maxn],id[maxn],tot=0,root=1;
     10 char s[10];
     11 inline void Rotate(int x,int kind){
     12   int y=pre[x];
     13   ch[y][!kind]=ch[x][kind];
     14   pre[ch[x][kind]]=y;
     15   if(pre[y])
     16     ch[pre[y]][ch[pre[y]][1]==y]=x;
     17   pre[x]=pre[y];
     18   ch[x][kind]=y;
     19   pre[y]=x;
     20   size[y]=size[ch[y][0]]+size[ch[y][1]]+1;
     21   size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
     22 }
     23 inline void splay(int r,int goal){
     24   while(pre[r]!=goal){
     25     if(pre[pre[r]]==goal)
     26       Rotate(r,ch[pre[r]][0]==r);
     27     else{
     28       int y=pre[r];
     29       int kind=ch[pre[y]][0]==y;
     30       if(ch[y][kind]==r){
     31     Rotate(r,!kind);
     32     Rotate(r,kind);
     33       }
     34       else{
     35     Rotate(y,kind);
     36     Rotate(r,kind);
     37       }
     38     }
     39   }
     40   if(goal==0) root=r;
     41 }
     42 void newnode(int &x,int fa,int keyy){
     43   x=++tot;
     44   pre[x]=fa;
     45   size[x]=1;
     46   key[x]=keyy;
     47 }
     48 void query(int x){
     49   int rt=root;
     50   while(x){
     51     if(size[ch[rt][0]]+1==x) break;
     52     if(size[ch[rt][0]]+1<x) x-=(size[ch[rt][0]]+1),rt=ch[rt][1];
     53     else rt=ch[rt][0];
     54   }
     55   printf("%d
    ",key[rt]);
     56 }
     57 void top(int x){
     58   int kt=id[x];
     59   splay(kt,0);
     60   if(!ch[kt][0]) return;
     61   int p1=ch[kt][0];
     62   while(ch[p1][1]) p1=ch[p1][1];
     63   splay(p1,root);
     64   if(!ch[kt][1]) root=ch[kt][0],pre[ch[kt][0]]=0;
     65   else{
     66     int p2=ch[kt][1];
     67     while(ch[p2][0]) p2=ch[p2][0];
     68     splay(p2,root);
     69     pre[p1]=0;
     70     pre[p2]=p1;
     71     ch[p1][1]=p2;
     72     root=p1;
     73   }
     74   int rt=p1;
     75   while(ch[rt][0]) rt=ch[rt][0];
     76   splay(rt,0);
     77   newnode(ch[root][0],root,x);
     78   size[root]=size[ch[root][0]]+size[ch[root][1]]+1;
     79   id[x]=ch[root][0];
     80 }
     81 void bottom(int x){
     82   int kt=id[x];
     83   splay(kt,0);
     84   if(!ch[kt][1]) return;
     85   int p1=ch[kt][1];
     86   while(ch[p1][0])
     87     p1=ch[p1][0];
     88   splay(p1,root);
     89   if(!ch[kt][0]) root=ch[kt][1],pre[ch[kt][1]]=0;
     90   else{
     91     int p2=ch[kt][0];
     92     while(ch[p2][1]) p2=ch[p2][1];
     93     splay(p2,root);
     94     pre[p1]=0;
     95     pre[p2]=p1;
     96     ch[p1][0]=p2;
     97     root=p1;
     98   }
     99   int rt=p1;
    100   while(ch[rt][1]) rt=ch[rt][1];
    101   splay(rt,0);
    102   newnode(ch[root][1],root,x);
    103   size[root]=size[ch[root][0]]+size[ch[root][1]]+1;
    104   id[x]=ch[root][1];
    105 }
    106 void Insert(int x){
    107   int k;
    108   scanf("%d",&k);
    109   if(k==0) return;
    110   splay(id[x],0);
    111   if(k==1){
    112     int rt=ch[root][1];
    113     if(rt==0) return;
    114     while(ch[rt][0]) rt=ch[rt][0];
    115     splay(rt,root);
    116     pre[ch[root][1]]=0;
    117     pre[ch[root][0]]=ch[root][1];
    118     ch[ch[root][1]][0]=ch[root][0];
    119     root=ch[root][1];
    120     rt=ch[root][1];
    121     size[root]++;
    122     if(rt==0) newnode(ch[root][1],root,x),id[x]=ch[root][1];
    123     else{
    124       while(ch[rt][0]) size[rt]++,rt=ch[rt][0];
    125       size[rt]++;
    126       newnode(ch[rt][0],rt,x);
    127       id[x]=ch[rt][0];
    128     }
    129   }
    130   else{
    131     int rt=ch[root][0];
    132     if(rt==0) return;
    133     while(ch[rt][1]) rt=ch[rt][1];
    134     splay(rt,root);
    135     pre[ch[root][0]]=0;
    136     pre[ch[root][1]]=ch[root][0];
    137     ch[ch[root][0]][1]=ch[root][1];
    138     root=ch[root][0];
    139     rt=ch[root][0];
    140     size[root]++;
    141     if(rt==0) newnode(ch[root][0],root,x),id[x]=ch[root][0];
    142     else{
    143       while(ch[rt][1]) size[rt]++,rt=ch[rt][1];
    144       size[rt]++;
    145       newnode(ch[rt][1],rt,x);
    146       id[x]=ch[rt][1];
    147     }
    148   }
    149 }
    150 void ask(int x){
    151   int k=id[x];
    152   splay(k,0);
    153   printf("%d
    ",size[ch[k][0]]);
    154 }
    155 int main()
    156 {
    157   int n,m,x;
    158   scanf("%d%d",&n,&m);
    159   scanf("%d",&x);
    160   id[x]=1;pre[1]=0;
    161   key[1]=x;
    162   size[1]=n;
    163   for(int i=2;i<=n;i++){
    164     scanf("%d",&x);
    165     ch[i-1][1]=i;
    166     pre[i]=i-1;
    167     size[i]=n-i+1;
    168     id[x]=i;
    169     key[i]=x;
    170   }
    171   if(n>2)
    172     splay(n/2,0);
    173   tot=n;
    174   for(int i=1;i<=m;i++){
    175     scanf("%s%d",s,&x);
    176     if(s[0]=='Q') query(x);
    177     if(s[0]=='T') top(x);
    178     if(s[0]=='B') bottom(x);
    179     if(s[0]=='I') Insert(x);
    180     if(s[0]=='A') ask(x);
    181   }
    182   return 0;
    183 }
    
    
    
     
  • 相关阅读:
    shell进行mysql统计
    java I/O总结
    Hbase源码分析:Hbase UI中Requests Per Second的具体含义
    ASP.NET Session State Overview
    What is an ISAPI Extension?
    innerxml and outerxml
    postman
    FileZilla文件下载的目录
    how to use webpart container in kentico
    Consider using EXISTS instead of IN
  • 原文地址:https://www.cnblogs.com/pantakill/p/6708376.html
Copyright © 2011-2022 走看看