zoukankan      html  css  js  c++  java
  • [LSGDOJ1822]书架 Splay

    题目描述

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

    输入

    第一行有两个数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本书的编号。

    输出

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

    样例输入

    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

    样例输出

    2 9 9 7 5 3

    提示

     30%的数据,n,m<=10000

    100%的数据,n,m<=80000
     
    题解:
    关键是开一个*id[i]保存编号为i的书所在节点的编号,然后在newnode的时候更新他的位置
    题目中
    Insert就是交换id[x]和他的前驱的id的值,然后再换节点对应的编号.
    Bottom就是删掉该节点,在把它的位置改成maxn+1(使得他的编号比任何一个节点都大,就达到了放在底端的效果),maxn表示当前最大的编号,并把maxn++.Top同理
    Query就是把x转到根,然后答案就是左子节点的size
    Ask 就是排名为k的数
    然后就开始乱搞
    我犯的低级错误:
    1.insert y=0时没特判
    2.把第一个数放在顶端也没特判
    代码如下:
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<cstdlib>
      7 #include<ctime>
      8 using namespace std;
      9 const int N=80005,INF=1999999999;
     10 struct node
     11 {
     12     int x,size,book;
     13     node *child[2],*fa;
     14 }a[N*4];
     15 node *pos=a,*root,*id[N];
     16 void newnode(node *&r,int key,node *ff,int number)
     17 {
     18     r=pos++;
     19     r->size=1,id[number]=r;
     20     r->x=key;r->fa=ff;r->book=number;
     21     r->child[0]=r->child[1]=NULL;
     22 }
     23 int gi()
     24 {
     25     int str=0;char ch=getchar();
     26     while(ch>'9' || ch<'0')ch=getchar();
     27     while(ch>='0'&& ch<='9')str=str*10+ch-'0',ch=getchar();
     28     return str;
     29 }
     30 int n,m;
     31 void updata(node *&r)
     32 {
     33     if(r){
     34         r->size=(r->child[0]?r->child[0]->size:0)+(r->child[1]?r->child[1]->size:0)+1;
     35         return ;
     36     }
     37 }
     38 void rotate(node *&r,bool t)
     39 {
     40     node *y=r->fa;
     41     y->child[!t]=r->child[t];
     42     if(r->child[t])r->child[t]->fa=y;
     43     r->fa=y->fa;
     44     if(y->fa)y->fa->child[y->fa->child[1]==y]=r;
     45     r->child[t]=y;
     46     y->fa=r;
     47     updata(y);
     48     updata(r);
     49     updata(r->fa);
     50 }
     51 void splay(node *r,node *g)
     52 {
     53     while(r->fa!=g)
     54     {
     55         if(r->fa->fa==g)rotate(r,r->fa->child[0]==r);
     56         else{
     57             node *y=r->fa;
     58             bool t=y->fa->child[0]==y;
     59             if(y->child[t]==r)rotate(r,!t);
     60             else rotate(y,t);
     61             rotate(r,t);
     62         }
     63     }
     64     if(g==NULL)root=r;
     65 }
     66 void insert(node *&r,int key,node *fa,int number)
     67 {
     68     if(r==NULL){
     69         newnode(r,key,fa,number);
     70         splay(r,NULL);
     71         return;
     72     }
     73     else insert(r->child[key>r->x],key,r,number);
     74 }
     75 node *pre,*nxt;
     76 char s[12];
     77 void getpre(node *r,int key)
     78 {
     79     if(!r)return ;
     80     if(r->x>=key)getpre(r->child[0],key);
     81     else pre=r,getpre(r->child[1],key);
     82 }
     83 void getnext(node *r,int key)
     84 {
     85     if(!r)return ;
     86     if(r->x<=key)getnext(r->child[1],key);
     87     else nxt=r,getnext(r->child[0],key);
     88 }
     89 void Ask(int x)
     90 {
     91     splay(id[x],NULL);
     92     printf("%d
    ",root->child[0]?root->child[0]->size:0);
     93     return ;
     94 }
     95 int getrank(node *r,int rk)
     96 {
     97     while(r){
     98         int d=r->child[0]?r->child[0]->size:0;
     99         if(rk==d+1)return r->book;
    100         if(rk<d+1)r=r->child[0];
    101         else rk-=d+1,r=r->child[1];
    102     }
    103     return -1;
    104 }
    105 node *findmax(node *r)
    106 {
    107     if(r->child[1])return findmax(r->child[1]);
    108     else return r;
    109 }
    110 int maxn=1,minn=1;
    111 void Delet(int x)
    112 {
    113     node *y;
    114     splay(id[x],NULL);
    115     if(root->child[0]){
    116         y=findmax(root->child[0]);
    117         splay(y,root);      
    118         y->child[1]=root->child[1];
    119         y->fa=NULL;
    120         if(root->child[1])
    121         root->child[1]->fa=y;
    122         root=y;
    123         updata(y);
    124     }
    125     else{
    126         root=root->child[1];
    127         root->fa=NULL;
    128     }
    129 }
    130 void Totop(int x,bool t)
    131 {
    132     Delet(x);
    133     if(!t)
    134     insert(root,--minn,NULL,x);
    135     else
    136     insert(root,++maxn,NULL,x);
    137 }
    138 void change(int x,int y)
    139 {
    140     node *kl;
    141     if(y==1)getnext(root,id[x]->x),kl=nxt;
    142     else getpre(root,id[x]->x),kl=pre;
    143     y=kl->book;
    144     swap(id[x],id[y]);
    145     swap(id[x]->book,id[y]->book);
    146 }
    147 int main()
    148 {
    149     int x,y;
    150     n=gi();m=gi();maxn=n;
    151     for(int i=1;i<=n;i++){
    152         x=gi();
    153         insert(root,i,NULL,x);
    154     }
    155     int cc=0;
    156     while(m--){
    157         scanf("%s%d",s,&x);
    158         if(s[0]=='A')Ask(x);
    159         else if(s[0]=='Q')printf("%d
    ",getrank(root,x));
    160         else if(s[0]=='I'){scanf("%d",&y);if(y)change(x,y);}
    161         else if(s[0]=='T')Totop(x,0);
    162         else if(s[0]=='B')Totop(x,1);
    163     }
    164     return 0;
    165 }
  • 相关阅读:
    Team Foundation Server 2010
    Visual Studio 2010 建模学习 与TFS工作项进行集成
    Asp.net动态生成页面控件的办法
    信息系统开发平台OpenExpressApp - 学习必备知识
    如何培养一个人:从育儿谈起
    ExtJS 资料
    在asp.net中动态生成web控件1
    团队发展五阶段
    C#动态生成控件以及添加事件处理
    Learn More,Study Less!
  • 原文地址:https://www.cnblogs.com/Yuzao/p/6816915.html
Copyright © 2011-2022 走看看