zoukankan      html  css  js  c++  java
  • BZOJ 1861: [Zjoi2006]Book 书架 (splay)

    1861: [Zjoi2006]Book 书架

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

    Day2

    ————————————————————————

    splay维护序列的裸题

    只需要维护一个子树大小size

    1.top 将一个点删除,插入到根节点最左儿子

    2.bottom 将一个点删除,插入到根节点最右儿子

    3.insert +1 -1 (记录s前一个点为prev,后一个点为next)

    -1 prev提根,s插在prev和它的左儿子之间

    +1 next提根,s插在next和它的右儿子之间

    4.ask  s提根,左儿子的size

    5.query 递归查找即可

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 #include <set>
      7 #include <vector>
      8 #include <string.h>
      9 #define siji(i,x,y) for(int i=(x);i<=(y);++i)
     10 #define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
     11 #define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
     12 #define sigongzi(j,x,y) for(int j=(x);j>(y);--j)
     13 #define inf 0x1f1f1f1f
     14 #define ivorysi
     15 #define mo 97797977
     16 #define hash 974711
     17 #define base 47
     18 #define MAXN 100005
     19 #define fi first
     20 #define se second
     21 #define pii pair<int,int>
     22 using namespace std;
     23 typedef long long ll;
     24 struct node {
     25     int size,son[2],fa;    
     26     void clear() {
     27         size=son[0]=son[1]=fa=0;
     28     }
     29 }tree[MAXN];
     30 int root;
     31 //维护size
     32 void update(int x,int c) {
     33     int k=tree[x].size;
     34     int o=tree[x].fa;
     35     tree[x].size=tree[o].size;
     36     tree[o].size=tree[o].size-k+tree[tree[x].son[c]].size;
     37 }
     38 void rotate(int x,int c) {
     39     update(x,c);
     40     int o=tree[x].fa;
     41     if(tree[o].fa!=0) {
     42         int t= o==tree[tree[o].fa].son[0] ? 0 : 1;
     43         tree[tree[o].fa].son[t]=x;
     44     }
     45     tree[o].son[c^1]=tree[x].son[c];
     46     if(tree[o].son[c^1])tree[tree[o].son[c^1]].fa=o;
     47     tree[x].son[c]=o;
     48     tree[x].fa=tree[o].fa;
     49     tree[o].fa=x;
     50     
     51 }
     52 void splay(int x,int y) {
     53     while(tree[x].fa!=y) {
     54         int k1= x==tree[tree[x].fa].son[0] ? 1 : 0;
     55         int k2= tree[x].fa == tree[tree[tree[x].fa].fa].son[0] ? 1 : 0;
     56         if(tree[tree[x].fa].fa!=y && k2==k1) {
     57             rotate(tree[x].fa,k1);
     58             rotate(x,k1);
     59         }
     60         else {
     61             rotate(x,k1);
     62         }
     63     }
     64     if(y==0) root=x;
     65     else {
     66 
     67     }
     68 }
     69 int find(int x,int c) {
     70     splay(x,0);
     71     int t=tree[x].son[c];
     72     while(tree[t].son[c^1]!=0) {
     73         t=tree[t].son[c^1];
     74     }
     75     return t;
     76 }
     77 void delete_x(int prev,int next) {
     78     if(prev!=0 && next!=0) {
     79         splay(prev,0);
     80         splay(next,prev);
     81         tree[tree[root].son[1]].son[0]=0;
     82         --tree[tree[root].son[1]].size;
     83     }
     84     else if(prev!=0) {
     85         splay(prev,0);
     86         tree[root].son[1]=0;
     87     }
     88     else {
     89         splay(next,0);
     90         tree[root].son[0]=0;
     91     }
     92     --tree[root].size;
     93 }
     94 //0是top 1是bottom
     95 void in_hurry(int x,int c) {
     96     int pr=find(x,0),ne=find(x,1);
     97     delete_x(pr,ne);
     98     int t=root;
     99     ++tree[t].size;
    100     tree[x].son[c^1]=tree[t].son[c];
    101     tree[tree[t].son[c]].fa=x;
    102     tree[x].size=tree[tree[t].son[c]].size+1;
    103     tree[x].fa=t;
    104     tree[t].son[c]=x;
    105 }
    106 int ask(int x) {
    107     splay(x,0);
    108     return tree[tree[x].son[0]].size;
    109 }
    110 void insert(int x,int c) {
    111     if(c==0) return;
    112     if(ask(x)==0 && c==-1) return;
    113     int pr=find(x,0),ne=find(x,1);
    114     delete_x(pr,ne);
    115     int t= c==-1 ? pr : ne;
    116     splay(t,0);
    117     c= c==-1 ? 0 : 1;
    118     ++tree[t].size;
    119     tree[x].clear();
    120     tree[x].son[c]=tree[t].son[c];
    121     tree[tree[t].son[c]].fa=x;
    122     tree[x].size=tree[tree[t].son[c]].size+1;
    123     tree[t].son[c]=x;
    124     tree[x].fa=t;
    125     splay(x,0);
    126 }
    127 
    128 void query(int x,int s) {
    129     int temp=tree[tree[x].son[0]].size+1;
    130     if(s==temp) {splay(x,0);return;}
    131     int t=s<temp ? 0 : 1;
    132     s = s>=temp ? s-temp : s; 
    133     query(tree[x].son[t],s);
    134 }
    135 int n,m;
    136 void init() {
    137     scanf("%d%d",&n,&m);
    138     int a=0,b;
    139     siji(i,1,n) {
    140         scanf("%d",&b);
    141         tree[b].fa=a;
    142         if(a!=0) { 
    143             tree[a].son[1]=b;
    144         }
    145         else {root=b;}
    146         tree[b].size=n-i+1;
    147         a=b;
    148     }
    149 
    150 }
    151 void solve() {
    152     init();
    153     char ord[15];
    154     int s,t;
    155     siji(i,1,m) {
    156         scanf("%s",ord);
    157         if(ord[0]=='T' || ord[0]=='B' ) {
    158             t=ord[0]=='T' ? 0 : 1;
    159             scanf("%d",&s);
    160             in_hurry(s,t);
    161         }
    162         else if(ord[0]=='I') {
    163             scanf("%d%d",&s,&t);
    164             insert(s,t);
    165         }
    166         else if(ord[0]=='A'){
    167             scanf("%d",&s);
    168             printf("%d
    ",ask(s));
    169         }
    170         else if(ord[0]=='Q') {
    171             scanf("%d",&s);
    172             query(root,s);
    173             printf("%d
    ",root);
    174         }
    175     }
    176 }
    177 int main(int argc, char const *argv[])
    178 {
    179 #ifdef ivorysi
    180     freopen("f1.in","r",stdin);
    181 #endif
    182     solve();
    183 }
  • 相关阅读:
    leetcode933
    leetcode929
    leetcode31
    leetcode29
    leetcode166
    2019-9-2-win10-uwp-保存用户选择文件夹
    2019-9-2-win10-uwp-保存用户选择文件夹
    2018-8-10-如何移动-nuget-缓存文件夹
    2018-8-10-如何移动-nuget-缓存文件夹
    2019-9-2-C#判断文件是否被混淆
  • 原文地址:https://www.cnblogs.com/ivorysi/p/6359106.html
Copyright © 2011-2022 走看看