码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI 2006] 书架

时间:2018-09-22 14:39:50      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:com   ret   www.   +=   pre   wap   lse   tar   lan   

[题目链接]

         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\n",T.ask(s));
                }
                if (op[0] == Q)
                {
                        scanf("%d",&s);
                        printf("%d\n",T.query(s));
                }
        }
        
        return 0;
    
}

 

[ZJOI 2006] 书架

标签:com   ret   www.   +=   pre   wap   lse   tar   lan   

原文地址:https://www.cnblogs.com/evenbao/p/9689711.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!