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

    基础平衡树操作,del+insert

    这道题就是还要记录一下平衡树中的编号和对应的书的编号,注意这两个都不是单调的

    写平衡树的时候,老是脑子有病。。总觉得平衡树里的标号是单调的。。

    这个也是模板没有修改前写的,常数较大。。。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 int read(){
      4   int x=0,f=1;char ch=getchar();
      5   while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
      6   while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
      7   return x*f;
      8 }
      9 #define N 80005
     10 int n,m,a[N],pos[N],root,sz[N],ch[N][2],fa[N];
     11 void pushup(int x){
     12   sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
     13 }
     14 void build(int l,int r,int f){
     15   int mid=l+r>>1;
     16   sz[mid]=1;fa[mid]=f;
     17   if(mid<f)ch[f][0]=mid;else ch[f][1]=mid;
     18   if(l==r)return;
     19   if(l<mid)build(l,mid-1,mid);
     20   if(r>mid)build(mid+1,r,mid);
     21   pushup(mid);
     22 }
     23 void rotate(int x,int &beto){
     24   int y=fa[x],t=ch[y][1]==x;
     25   if(y!=beto)ch[fa[y]][ch[fa[y]][1]==y]=x;else beto=x;
     26   fa[x]=fa[y];fa[y]=x;
     27   fa[ch[x][!t]]=y;
     28   ch[y][t]=ch[x][!t];
     29   ch[x][!t]=y;
     30   pushup(y);pushup(x);
     31 }
     32 void splay(int x,int &beto){
     33   while(x!=beto){
     34     int y=fa[x];
     35     if(y!=beto){
     36       if((ch[fa[y]][1]==y)==(ch[y][1]==x))rotate(y,beto);
     37       else rotate(x,beto);
     38     }rotate(x,beto);
     39   }
     40 }
     41 int find_k(int x,int k){
     42   if(sz[ch[x][0]]==k-1)return x;
     43   if(sz[ch[x][0]]<k-1)return find_k(ch[x][1],k-sz[ch[x][0]]-1);
     44   return find_k(ch[x][0],k);
     45 }
     46 void del(int x){
     47   int l=find_k(root,x-1),r=find_k(root,x+1);
     48   splay(l,root);splay(r,ch[l][1]);
     49   x=ch[r][0];ch[r][0]=0;
     50   pushup(r);pushup(l);
     51 }
     52 int main(){
     53   n=read();m=read();n+=2;
     54   for(int i=2;i<n;i++)a[i]=read(),pos[a[i]]=i;
     55   build(1,n,0);root=(1+n)>>1;
     56   char s[10];int x;
     57   for(int i=1;i<=m;i++){
     58     scanf("%s",s);x=read();
     59     if(s[0]=='T'){
     60       int p=pos[x],rk;
     61       splay(p,root);rk=sz[ch[p][0]]+1;
     62       del(rk);
     63       int l=find_k(root,1),r=find_k(root,2);
     64       splay(l,root);splay(r,ch[l][1]);
     65       ch[r][0]=p;fa[p]=r;
     66       pushup(r);pushup(l);
     67     }
     68     else if(s[0]=='B'){
     69       int p=pos[x],rk;
     70       splay(p,root);rk=sz[ch[p][0]]+1;
     71       del(rk);
     72       int l=find_k(root,n-2),r=find_k(root,n-1);
     73       splay(l,root);splay(r,ch[l][1]);
     74       ch[r][0]=p;fa[p]=r;
     75       pushup(r);pushup(l);
     76     }
     77     else if(s[0]=='I'){
     78       int t=read();
     79       int p=pos[x],rk;
     80       splay(p,root);rk=sz[ch[p][0]]+1;
     81       del(rk);
     82       int l=find_k(root,rk+t-1),r=find_k(root,rk+t);
     83       splay(l,root);splay(r,ch[l][1]);
     84       ch[r][0]=p;fa[p]=r;
     85       pushup(r);pushup(l);
     86     }
     87     else if(s[0]=='A'){
     88       int p=pos[x],rk;
     89     //  cout<<"p "<<p<<endl;
     90       splay(p,root);rk=sz[ch[p][0]]+1;
     91     //  cout<<"rk "<<rk<<endl;
     92       printf("%d
    ",rk-2);
     93     }
     94     else if(s[0]=='Q'){
     95       int p=find_k(root,x+1);
     96       printf("%d
    ",a[p]);
     97     }
     98   }
     99   return 0;
    100 }
    View Code

    1861: [Zjoi2006]Book 书架

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 1183  Solved: 689
    [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
  • 相关阅读:
    go学习笔记day19
    Mac11系统 SIP保护 如何在根目录创建data文件夹
    vue首页加载文件过多,去掉预加载
    NPM更换国内源
    autoCAD2007 图层
    读《现代JavaScript》笔记①——Map and Set(映射和集合)
    pubsubjs发布订阅
    vuecli中配置less并使用全局变量
    React组件通讯
    v6版reactrouterdom的改变
  • 原文地址:https://www.cnblogs.com/wjyi/p/5612288.html
Copyright © 2011-2022 走看看