zoukankan      html  css  js  c++  java
  • [题解]bzoj 1861 Book 书架

    1861: [Zjoi2006]Book 书架

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

    [Submit][Status][Discuss]

      将用Splay按照下标来建树,另外用一个数组来记录编号为i的书在Splay中的位置(指针)。

      Top、Bottom和Insert操作就把该节点删掉,然后重新取出来,然后插到对应的位置。

      Ask操作把对应节点伸展到根,然后求左子树的大小。Query操作就求K小值就行了。

    Code

      1 /**
      2  * bzoj
      3  * Problem#1861
      4  * Accepted
      5  * Time:1280ms
      6  * Memory:3464k
      7  */
      8 #include<iostream>
      9 #include<fstream>
     10 #include<sstream>
     11 #include<cstdio>
     12 #include<cstdlib>
     13 #include<cstring>
     14 #include<ctime>
     15 #include<cctype>
     16 #include<cmath>
     17 #include<algorithm>
     18 #include<stack>
     19 #include<queue>
     20 #include<set>
     21 #include<map>
     22 #include<vector>
     23 using namespace std;
     24 typedef bool boolean;
     25 #define smin(a, b)    (a) = min((a), (b))
     26 #define smax(a, b)    (a) = max((a), (b))
     27 template<typename T>
     28 inline void readInteger(T& u){
     29     char x;
     30     int aFlag = 1;
     31     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     32     if(x == -1)    return;
     33     if(x == '-'){
     34         x = getchar();
     35         aFlag = -1;
     36     }
     37     for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
     38     ungetc(x, stdin);
     39     u *= aFlag;
     40 }
     41 
     42 template<typename T>
     43 class SplayNode{
     44     public:
     45         T data;
     46         int s;
     47         SplayNode* next[2];
     48         SplayNode* father;
     49         SplayNode(T data, SplayNode* father):data(data), father(father), s(1){
     50             memset(next, 0, sizeof(next));
     51         }
     52         inline void maintain(){
     53             this->s = 1;
     54             for(int i = 0; i < 2; i++)
     55                 if(next[i] != NULL)
     56                     s += next[i]->s;
     57         }
     58         int which(SplayNode* p){
     59             return (next[0] == p) ? (0) : (1);
     60         }
     61 };
     62 
     63 template<typename T>
     64 class Splay{
     65     protected:
     66         inline static void rotate(SplayNode<T>*& node, int d){
     67             SplayNode<T> *father = node->father;
     68             SplayNode<T> *newRoot = node->next[d ^ 1];
     69             node->next[d ^ 1] = newRoot->next[d];
     70             node->father = newRoot;
     71             newRoot->next[d] = node;
     72             newRoot->father = father;
     73             if(node->next[d ^ 1] != NULL)    node->next[d ^ 1]->father = node;
     74             if(father != NULL)    father->next[father->which(node)] = newRoot;
     75             node->maintain();
     76             node->father->maintain();
     77         }
     78         
     79         static SplayNode<T>* findKth(SplayNode<T>*& node, int k){
     80             int ls = (node->next[0] != NULL) ? (node->next[0]->s) : (0);
     81             if(k == ls + 1)    return node;
     82             if(k <= ls)    return findKth(node->next[0], k);
     83             return findKth(node->next[1], k - ls - 1);
     84         }        
     85         
     86     public:
     87         SplayNode<T>* root;
     88         
     89         Splay():root(NULL){    }
     90         
     91         inline void splay(SplayNode<T>*& node, SplayNode<T>* father){
     92             while(node->father != father){
     93                 SplayNode<T>* f = node->father;
     94                 int fd = f->which(node);
     95                 SplayNode<T>* ff = f->father;
     96                 if(ff == father){
     97                     rotate(f, fd ^ 1);
     98                     break;
     99                 }
    100                 int ffd = ff->which(f);
    101                 if(fd == ffd){
    102                     rotate(ff, ffd ^ 1);
    103                     rotate(f, fd ^ 1);
    104                 }else{
    105                     rotate(f, fd ^ 1);
    106                     rotate(ff, ffd ^ 1);
    107                 }
    108             }
    109             if(father == NULL)
    110                 root = node;
    111         }
    112         
    113         inline SplayNode<T>* findKth(int k, SplayNode<T>* father){
    114             if(root == NULL || k < 1 || k > root->s)    return NULL;
    115             SplayNode<T>* res = findKth(root, k);
    116             splay(res, father);
    117             return res;
    118         }        
    119         
    120         inline void insert(T data, int index){
    121             if(root == NULL){
    122                 root = new SplayNode<T>(data, NULL);
    123                 return;
    124             }
    125             SplayNode<T>* added;
    126             if(index <= 1){
    127                 findKth(1, NULL);
    128                 added = root->next[0] = new SplayNode<T>(data, root);
    129             }else if(index >= root->s + 1){
    130                 findKth(root->s, NULL);
    131                 added = root->next[1] = new SplayNode<T>(data, root);
    132             }else if(index == root->s){
    133                 findKth(index, NULL);
    134                 findKth(index - 1, root);
    135                 added = new SplayNode<T>(data, root);
    136                 added->next[0] = root->next[0];
    137                 root->next[0]->father = added;
    138                 root->next[0] = added;
    139             }else{
    140                 findKth(index - 1, NULL);
    141                 findKth(index + 1, root);
    142                 SplayNode<T>* node = root->next[1]->next[0];
    143                 added = node->next[0] = new SplayNode<T>(data, node);
    144             }
    145             splay(added, NULL);
    146         }
    147         
    148         inline void remove(SplayNode<T>* node){
    149             splay(node, NULL);
    150             SplayNode<T>* maxi = node->next[0];
    151             if(maxi == NULL){
    152                 root = node->next[1];
    153                 if(node->next[1] != NULL)    node->next[1]->father = NULL;
    154                 delete node;
    155                 return;
    156             }
    157             while(maxi->next[1] != NULL) maxi = maxi->next[1];
    158             splay(maxi, node);
    159             maxi->next[1] = node->next[1];
    160             if(node->next[1] != NULL)    node->next[1]->father = maxi;
    161             maxi->father = NULL;
    162             delete node;
    163             root = maxi;
    164             maxi->maintain();
    165         }
    166         
    167 };
    168 
    169 int n, m;
    170 Splay<int> s;
    171 SplayNode<int>** books;
    172 
    173 inline void init(){
    174     readInteger(n);
    175     readInteger(m);
    176     books = new SplayNode<int>*[(const int)(n + 1)];
    177     for(int i = 1, a; i <= n; i++){
    178         readInteger(a);
    179         s.insert(a, i);
    180         books[a] = s.root;
    181     }
    182 }
    183 
    184 inline void solve(){
    185     char cmd[10];
    186     int a, b;
    187     while(m--){
    188         scanf("%s", cmd);
    189         readInteger(a);
    190         if(cmd[0] == 'T'){
    191             s.remove(books[a]);
    192             s.insert(a, 1);
    193             books[a] = s.root;
    194         }else if(cmd[0] == 'B'){
    195             s.remove(books[a]);
    196             s.insert(a, n);
    197             books[a] = s.root;
    198         }else if(cmd[0] == 'I'){
    199             readInteger(b);
    200             if(b == 0)    continue;
    201             s.splay(books[a], NULL);
    202             int r = (s.root->next[0] == NULL) ? (0) : (s.root->next[0]->s);
    203             s.remove(books[a]);
    204             s.insert(a, r + 1 + b);
    205             books[a] = s.root;
    206         }else if(cmd[0] == 'A'){
    207             s.splay(books[a], NULL);
    208             int r = (s.root->next[0] == NULL) ? (0) : (s.root->next[0]->s);
    209             printf("%d
    ", r);
    210         }else if(cmd[0] == 'Q'){
    211             SplayNode<int> *node = s.findKth(a, NULL);
    212             printf("%d
    ", node->data);
    213         }
    214     }
    215 }
    216 
    217 int main(){
    218     init();
    219     solve();
    220     return 0;
    221 }
  • 相关阅读:
    Tensorflow入门:Linear Regression
    日语动词变形总结
    序列模型第二周作业2:Emojify!
    序列模型第二周作业1:Operations on word vectors
    序列模型第一周作业3: Improvise a Jazz Solo with an LSTM Network
    序列模型第一周作业2: Character level language model
    序列模型第一周作业1: Building your Recurrent Neural Network
    Bidirectional RNN (BRNN)
    Long Short term memory unit(LSTM)
    propertyGrid使用
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6287878.html
Copyright © 2011-2022 走看看