首页 > 代码库 > wikioi 1514 and ZJOI2006 书架

wikioi 1514 and ZJOI2006 书架

 

1514 书架 

 0人推荐  收藏 发题解

题目描述 Description

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

输入描述 Input Description

第一行有两个数 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 Description

对于每一条 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






3

数据范围及提示 Data Size & Hint

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

题解:

神奇的splay!

我觉得刚开始的时候以序号按BST建树,

建好树之后在删除、加入的时候只是人为定义它的位置或者rank,

它的编号已经不代表什么了,而它的编号因为一直不变所以可以为我们做一些事情,比如本题

因此splay也可以回收废节点

。。。语言表达能力有限。。。

哪里说得不对请神牛指出

代码:

  1 const maxn=80000+100;inf=maxlongint>>1;  2 var i,n,m,x,t,rt:longint;  3     ch:char;  4     s,pos,v,fa,a:array[0..maxn] of longint;  5     c:array[0..maxn,0..1] of longint;  6 procedure pushup(x:longint);  7  begin  8    s[x]:=s[c[x,0]]+s[c[x,1]]+1;  9  end; 10 procedure rotate(x:longint;var k:longint); 11  var l,r,y,z:longint; 12  begin 13    y:=fa[x];z:=fa[y]; 14    l:=ord(c[y,1]=x);r:=l xor 1; 15    if y=k then k:=x else c[z,ord(c[z,1]=y)]:=x; 16    fa[x]:=z;fa[y]:=x;fa[c[x,r]]:=y; 17    c[y,l]:=c[x,r];c[x,r]:=y; 18    pushup(y);pushup(x); 19  end; 20 procedure splay(x:longint;var k:longint); 21  var y,z:longint; 22  begin 23    while x<>k do 24     begin 25       y:=fa[x];z:=fa[y]; 26       if y<>k then 27          if (c[z,0]=y) xor (c[y,0]=x) then rotate(x,k) 28          else rotate(y,k); 29       rotate(x,k); 30     end; 31  end; 32 function find(x,rank:longint):longint; 33  var l,r:longint; 34  begin 35    l:=c[x,0];r:=c[x,1]; 36    if s[l]+1=rank then exit(x) 37    else if s[l]>=rank then exit(find(l,rank)) 38    else exit(find(r,rank-s[l]-1)); 39  end; 40 procedure del(k:longint); 41  var x,y,z:longint; 42  begin 43    x:=find(rt,k-1);y:=find(rt,k+1); 44    splay(x,rt);splay(y,c[x,1]); 45    z:=c[y,0];fa[z]:=0;s[z]:=0;c[y,0]:=0; 46    pushup(y);pushup(x); 47  end; 48  49 procedure build(l,r,f:longint); 50  var mid,now,last:longint; 51  begin 52    if l>r then exit; 53    mid:=(l+r)>>1; 54    now:=mid;last:=f; 55    fa[now]:=last;v[now]:=a[mid]; 56    c[last,ord(mid>f)]:=now; 57    if l=r then 58      begin 59       s[now]:=1; 60       exit; 61      end; 62    build(l,mid-1,mid);build(mid+1,r,mid); 63    pushup(now); 64  end; 65  66 procedure init; 67  begin 68    readln(n,m); 69    for i:=2 to n+1 do read(a[i]);readln; 70    for i:=2 to n+1 do pos[a[i]]:=i; 71    build(1,n+2,0);rt:=(n+3)>>1; 72  end; 73 procedure move(k,val:longint); 74  var x,y,z,rank:longint; 75  begin 76    if val=0 then exit; 77    z:=pos[k];splay(z,rt);rank:=s[c[z,0]]+1;del(rank); 78    if val=inf then begin x:=find(rt,n);y:=find(rt,n+1);end 79    else if val=-inf then begin x:=find(rt,1);y:=find(rt,2);end 80    else begin x:=find(rt,rank+val-1);y:=find(rt,rank+val);end; 81    splay(x,rt);splay(y,c[x,1]); 82    fa[z]:=y;s[z]:=1;c[y,0]:=z; 83    pushup(y);pushup(x); 84  end; 85 procedure main; 86  begin 87    for i:=1 to m do 88     begin 89       read(ch); 90       case ch of 91       T:begin 92            while ch<>  do read(ch); 93            readln(x);move(x,-inf); 94           end; 95       B:begin 96            while ch<>  do read(ch); 97            readln(x);move(x,inf); 98           end; 99       I:begin100            while ch<>  do read(ch);101            readln(x,t);move(x,t);102           end;103       A:begin104            while ch<>  do read(ch);105            readln(x);106            splay(pos[x],rt);writeln(s[c[rt,0]]-1);107           end;108       Q:begin109            while ch<>  do read(ch);110            readln(x);111            writeln(v[find(rt,x+1)]);112           end;113        end;114     end;115  end;116 begin117   assign(input,input.txt);assign(output,output.txt);118   reset(input);rewrite(output);119   init;120   main;121   close(input);close(output);122 end.123           
View Code