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 }
    
    
    
     
  • 相关阅读:
    [转载]杨建:网站加速--动态应用篇 (下)
    [转载]杨建:网站加速--动态应用篇 (下)
    [转载]正则表达式 30分钟入门 教程
    [转载]正则表达式 30分钟入门 教程
    Single Number
    数据库应该使用异步吗 Should my database calls be Asynchronous?
    C# return dynamic/anonymous type value as function result
    Entity Framework: 视图查询时重复返回第一行值, duplicate frst rows in resultset from a view
    wysiwyg editor
    shutdown computer in ad and ou
  • 原文地址:https://www.cnblogs.com/pantakill/p/6708376.html
Copyright © 2011-2022 走看看