[ZJOI 2006] 书架

Posted evenbao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ZJOI 2006] 书架相关的知识,希望对你有一定的参考价值。

[题目链接]

         https://www.lydsy.com/JudgeOnline/problem.php?id=1861

[算法]

        平衡树

        时间复杂度 : O(M log N)

[代码]

             

#include<bits/stdc++.h>
using namespace std;
#define MAXN 800010

int n,m;
int a[MAXN];

struct Splay
{
        int root , total;
        int pos[MAXN];
        Splay()
        {
                root = total = 0;
                memset(pos,0,sizeof(pos));
        }
        struct Node
        {
                int fa;
                int value,size;
                int son[2];    
        }    Tree[MAXN];
        inline bool get(int x)
        {
                return Tree[Tree[x].fa].son[1] == x; 
        }
            inline void splay(int x)
        {
                for (int fa = Tree[x].fa; (fa = Tree[x].fa); rotate(x))
                        rotate(get(x) == get(fa) ? fa : x);
                root = x;
        }
        inline void push_back(int x)
        {
                if (!root)
                {
                        root = pos[x] = ++total;
                        Tree[root].fa = 0;
                        Tree[root].son[0] = Tree[root].son[1] = 0;
                        Tree[root].value = x;
                        Tree[root].size = 1;
                        return;
                }
                int now = root;
                while (Tree[now].son[1]) now = Tree[now].son[1];
                Tree[now].son[1] = pos[x] = ++total;
                Tree[total].fa = now;
                Tree[total].son[0] = Tree[total].son[1] = 0;
                Tree[total].value = x;
                Tree[total].size = 1;
                splay(total);
        }
        inline void update(int x)
        {
                Tree[x].size = 1;
                Tree[x].size += Tree[Tree[x].son[0]].size;
                Tree[x].size += Tree[Tree[x].son[1]].size;
        }
        inline void rotate(int x)
        {
                int f = Tree[x].fa , g = Tree[f].fa;
                int tmpx = get(x) , tmpf = get(f);
                if (!f) return;
                Tree[f].son[tmpx] = Tree[x].son[tmpx ^ 1];
                if (Tree[x].son[tmpx ^ 1]) Tree[Tree[x].son[tmpx ^ 1]].fa = f;
                Tree[x].son[tmpx ^ 1] = f;
                Tree[f].fa = x;
                if (g) Tree[g].son[tmpf] = x;
                Tree[x].fa = g;
                update(f);
                update(x);
        }    
        inline int find(int x)
        {
                int now = root;
                while (now)
                {
                        if (Tree[now].son[0] && x <= Tree[Tree[now].son[0]].size) now = Tree[now].son[0];
                        else
                        {
                                int sz = 1;
                                if (Tree[now].son[0]) sz += Tree[Tree[now].son[0]].size;
                                if (x == sz) return now;
                                x -= sz;
                                now = Tree[now].son[1];
                        }
                }
        }
        inline void erase(int x)
        {
                int id = pos[x];
                splay(id);
                if (!Tree[root].son[0] && !Tree[root].son[1])
                {
                        Tree[root].size = Tree[root].value = 0;
                        Tree[root].fa = 0;
                        Tree[root].son[0] = Tree[root].son[1] = 0;
                        root = 0;
                        return;
                }
                if (!Tree[root].son[0])
                {
                        int tmp = root;
                        root = Tree[root].son[1];
                        Tree[root].fa = 0;
                        Tree[tmp].size = Tree[tmp].value = 0;
                        Tree[tmp].son[0] = Tree[tmp].son[1] = 0;
                        return;
                }
                if (!Tree[root].son[1])
                {
                        int tmp = root;
                        root = Tree[root].son[0];
                        Tree[root].fa = 0;
                        Tree[tmp].size = Tree[tmp].value = 0;
                        Tree[tmp].son[0] = Tree[tmp].son[1] = 0;
                        return;
                }
                int now = Tree[root].son[0];
                while (Tree[now].son[1]) now = Tree[now].son[1];
                splay(now);
                Tree[now].son[1] = Tree[id].son[1];
                Tree[Tree[id].son[1]].fa = now;
                Tree[id].fa = 0;
                pos[Tree[id].value] = 0;
                Tree[id].size = Tree[id].value = 0;
                Tree[id].son[0] = Tree[id].son[1] = 0;
                update(root);
        }
        inline void insert_left(int x)
        {
                Tree[root].son[0] = ++total;
                Tree[total].fa = root;
                Tree[total].son[0] = Tree[total].son[1] = 0;
                Tree[total].value = x;
                Tree[total].size = 1;
                pos[x] = total;
                update(root);        
        }
        inline void insert_right(int x)
        {
                Tree[root].son[1] = ++total;
                Tree[total].fa = root;
                Tree[total].son[0] = Tree[total].son[1] = 0;
                Tree[total].value = x;
                Tree[total].size = 1;
                pos[x] = total;
                update(root);    
        }
        inline void Swap(int x,int y)
        {
                int posx = pos[x];
                splay(posx);
                int posy;
                if (y == -1)
                {
                        if (!Tree[posx].son[0]) return;
                        posy = Tree[posx].son[0];
                        while (Tree[posy].son[1]) posy = Tree[posy].son[1];
                } else
                {
                        if (!Tree[posx].son[1]) return;
                        posy = Tree[posx].son[1];
                        while (Tree[posy].son[0]) posy = Tree[posy].son[0];
                }
                swap(pos[Tree[posx].value],pos[Tree[posy].value]);
                swap(Tree[posx].value,Tree[posy].value);    
        }
        inline int ask(int x)
        {
                splay(pos[x]);
                return Tree[Tree[root].son[0]].size;
        }
        inline int query(int x)
        {
                int ret = find(x);
                return Tree[ret].value;
        }
} T;

int main()
{
        
        scanf("%d%d",&n,&m);
        for (int i = 1; i <= n; i++) 
        {
                scanf("%d",&a[i]);
                T.push_back(a[i]);
        }
        for (int i = 1; i <= m; i++)
        {
                char op[10];
                int s,t;
                scanf("%s",op);
                if (op[0] == T)
                {
                        scanf("%d",&s);
                        if (n == 1) continue;
                        T.erase(s);
                        int x = T.find(1);
                        T.splay(x);
                        T.insert_left(s);
                }
                if (op[0] == B)
                {
                        scanf("%d",&s);
                        if (n == 1) continue;
                        T.erase(s);
                        int x = T.find(n - 1);
                        T.splay(x);
                        T.insert_right(s);
                }
                if (op[0] == I)
                {
                        scanf("%d%d",&s,&t);
                        if (t == 0) continue;
                        T.Swap(s,t);
                }
                if (op[0] == A)
                {
                        scanf("%d",&s);
                        printf("%d
",T.ask(s));
                }
                if (op[0] == Q)
                {
                        scanf("%d",&s);
                        printf("%d
",T.query(s));
                }
        }
        
        return 0;
    
}

 

以上是关于[ZJOI 2006] 书架的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1861 [Zjoi2006]Book 书架 ——Splay

[Zjoi2006]Book 书架

P2596 [ZJOI2006]书架

[ZJOI2006]书架

[ZJOI2006] 书架

BZOJ 1861: [Zjoi2006]Book 书架 (splay)