就是给你一摞书,然后又询问第k大,编号为x的书是第几大,然后修改书的位置

splay模板题。。。然而我还是不会,,,又遇到lrj的书的坑了,rj的书里没有father,顿时弄得我ask不会搞了

注意合并和分离的时候考虑一下会不会出空树,如果是空树就会RE,特判一下



#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node{
    Node *ch[2];
    Node *father;
    int s;
    int v;
    inline int cmp(int x){
        int ret = 0;
        if(ch[0] != NULL) ret += ch[0] -> s;
        if(x <= ret) return 0;
        ret ++;
        if(ret == x) return -1;
        return 1;
    }
    inline void maintain(){
        s = 1;
        if(ch[0] != NULL) s += ch[0] -> s;
        if(ch[1] != NULL) s += ch[1] -> s;
        return;
    }
};
struct Splay{
    Node ft[100000];
    int size;
    Node *p;
    int num[100000];
    int a[100000];
    inline void init(){
        size = 0;
        p -> ch[0] = p -> ch[1] = p -> father = NULL;
        return;
    }
    inline void rotate(Node* &o, int d){
        Node* k = o -> ch[d ^ 1]; o -> ch[d ^ 1] = k -> ch[d]; k -> ch[d] = o;
        o -> maintain(); k -> maintain(); o = k;
        o -> father = o -> ch[d] -> father;
        if(o -> ch[d] -> ch[d ^ 1] != NULL) o -> ch[d] -> ch[d ^ 1] -> father = o -> ch[d];
        o -> ch[d] -> father = o;
        return;
    }
    inline void insert(Node* &o, int l, int r){
        if(r < l) return;
        int mid = (l + r) / 2;
        o = &ft[size]; size ++;
        o -> ch[0] = o -> ch[1] = o -> father = NULL;
        o -> v = a[mid];
        num[o -> v] = size - 1;
        if(l != r){
            insert(o -> ch[0], l, mid - 1);
            if(o -> ch[0] != NULL) o -> ch[0] -> father = o;
            insert(o -> ch[1], mid + 1, r);
            if(o -> ch[1] != NULL) o -> ch[1] -> father = o;
        }
        o -> maintain();
        return;
    }
    inline void splay(Node* &o, int k){
        int d = o -> cmp(k);
        if(d == 1 && o -> ch[0] != NULL) k = k - o -> ch[0] -> s - 1;
        else if(d == 1) k --;
        if(d != -1){
            Node* w = o -> ch[d];
            int d2 = w -> cmp(k);
            int k2 = k;
            if(d2 != 0 && w -> ch[0] != NULL) k2 = k2 - w -> ch[0] -> s - 1;
            else if(d2 != 0) k2 --;
            if(d2 != -1){
                splay(w -> ch[d2], k2);
                if(d == d2) rotate(o, d ^ 1);
                else rotate(o -> ch[d], d);
            }
            rotate(o, d ^ 1);
        }
        return;
    }
    inline Node* merge(Node* left, Node* right){
        if(left == NULL) return right;
        if(right == NULL) return left;
        splay(left, left -> s);
        left -> ch[1] = right;
        left -> ch[1] -> father = left;
        left -> maintain();
        return left;
    }
    inline void split(Node* o, int k, Node* &left, Node* &right){
        if(k == 0){
            left = NULL;
            right = o;
            return;
        }
        splay(o, k);
        left = o;
        right = o -> ch[1];
        if(right != NULL) right -> father = NULL;
        left -> ch[1] = NULL;
        left -> maintain();
        return;
    }
    inline int rank(Node* &o, int k){
        int d = o -> cmp(k);
        if(d == -1) return o -> v;
        int st = 0;
        if(o -> ch[0] != NULL) st = o -> ch[0] -> s;
        if(d == 1) k = k - st - 1;
        return rank(o -> ch[d], k);
    }
    inline int ask(int k){
        int ret = 0;
        Node* o = &ft[num[k]];
        if(o -> ch[0] != NULL) ret = o -> ch[0] -> s;
        while(o -> father != NULL){
            if(o -> father -> ch[1] == o){
                int u = 0;
                if(o -> father -> ch[0] != NULL) u = o -> father -> ch[0] -> s;
                ret += (u + 1);
            }
            o = o -> father;
        }
        return ret;
    }
    inline void Top(int k){
        int t = ask(k) + 1;
        Node *left, *mid, *right;
        split(p, t, left, right);
        split(left, t - 1, left, mid);
        left = merge(mid, left);
        left = merge(left, right);
        p = left;
        return;
    }
    inline void Bottom(int k){
        int t = ask(k) + 1;
        Node *left, *mid, *right;
        split(p, t, left, right);
        split(left, t - 1, left, mid);
        left = merge(left, right);
        left = merge(left, mid);
        p = left;
        return;
    }
    inline void Insert(int k, int w){
        int t = ask(k) + 1;
        Node *left, *mid, *right;
        split(p, t, left, right);
        split(left, t - 1, left, mid);
        left = merge(left, right);
        split(left, t + w - 1, left, right);
        left = merge(left, mid);
        left = merge(left, right);
        p = left;
        return;
    }
} wt;
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++) scanf("%d", &wt.a[i]);
    wt.insert(wt.p, 1, n);
    char str[20];
    for(int i = 1; i <= m; i ++){
        scanf("%s", str);
        int k, w;
        if(str[0] == 'Q'){
            scanf("%d", &k);
            printf("%d\n", wt.rank(wt.p, k));
        }
        else if(str[0] == 'A'){
            scanf("%d", &k);
            printf("%d\n", wt.ask(k));
        }
        else if(str[0] == 'T'){
            scanf("%d", &k);
            wt.Top(k);
        }
        else if(str[0] == 'B'){
            scanf("%d", &k);
            wt.Bottom(k);
        }
        else{
            scanf("%d%d", &k, &w);
            wt.Insert(k, w);
        }
    }
    return 0;
} 

BZOJ1861——book的更多相关文章

  1. [BZOJ1861][Zjoi2006]Book 书架

    [BZOJ1861][Zjoi2006]Book 书架 试题描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候 ...

  2. bzoj1861

    bzoj1861[ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本 ...

  3. bzoj1861 书架

    bzoj1861 书架 原题链接 神题... 先吐槽洛谷的样例 10 10 1 3 2 7 5 8 10 4 9 6 Query 3 Top 5 Ask 6 Bottom 3 Ask 3 Top 6 ...

  4. [bzoj1861][Zjoi2006]Book 书架_非旋转Treap

    Book 书架 bzoj-1861 Zjoi-2006 题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底):将指定编号元素左右篡位:查询指定编号元素位置:查询指定数量位置元素编号. ...

  5. BZOJ-1861 Book 书架 Splay

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 1010 Solved: 588 [Submit][Stat ...

  6. BZOJ1861[ZJOI2006]Book书架

    Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下 ...

  7. 【BZOJ1861】【splay】Book 书架

    Description 小 T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿 ...

  8. [BZOJ1861][ZJOI2006]书架

    BZOJ Luogu Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看 ...

  9. BZOJ1861[Zjoi2006]书架——非旋转treap

    题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些 ...

随机推荐

  1. Emgu学习之(四)——图像阈值

    http://www.cnblogs.com/CoverCat/p/5043833.html Visual Studio Community 2015 工程和代码:http://pan.baidu.c ...

  2. 之前总结的今天给大分享一下iOS

    退回输入键盘 苹果 ios 开发一年的工作笔记 - (BOOL) textFieldShouldReturn:(id)textField{ [textField resignFirstResponde ...

  3. WPF:父窗口与子窗口的层次关系

    关于子窗体的层级关系总结一下哈,希望能对大家有些帮助 假设有这样两个窗体:RootWindow,SubWindow,在RootWindow中引发某事件而显示SubWindow 1,如果弹出窗体(比如S ...

  4. B450黑苹果之路(1)

    安装黑苹果,采取的是懒人版写入磁盘分区中,然后再安装1)从硬盘中分两个区,一个是未来使用的目标分区,一个是磁盘镜像区2)由于HFS+支持逻辑分区,所以两个分区都放逻辑分区上,分区不格式化3)使用硬盘助 ...

  5. Win7 配置Apache+PHP+Mysql环境

    第一.安装并配置APACHE(安装到D:\phpapache\Apache2.2) 1.安装时默认安装,Network Domain, Server Name 我填写我的计算机名,Administra ...

  6. php操作redis

    redis的操作很多的,以前看到一个比较全的博客,但是现在找不到了.查个东西搜半天,下面整理一下php处理redis的例子,个人觉得常用一些例子.下面的例子都是基于php-redis这个扩展的. 1, ...

  7. C++中public,protected,private派生类继承问题和访问权限问题

    C++中public,protected,private派生类继承问题和访问权限问题 当一个子类从父类继承时,父类的所有成员成为子类的成员,此时对父类成员的访问状态由继承时使用的继承限定符决定. 1. ...

  8. yourtour的几种链接

    php,html {:URL('User-Register/index')}    格式:http://www.xxx.com/index.php?g=User&m=User&a=in ...

  9. thinkphp succes error跳转模板 设置

    执行成功 换成自己想要的模块 下面的路径是默认的模板\ThinkPHP\Tpl\dispatch_jump.tpl D:\wamp\www\ThinkPHP\Tpl\dispatch_jump.tpl ...

  10. 工具,如何去掉百度编辑器 ueditor 元素路径、字数统计等

    去掉如下截图: 在百度编辑器 ueditor 根目录下: ueditor.config.js 文件中 搜索并将参数elementPathEnabled设置成false即可 常用功能开关如下: ,ele ...