zoukankan      html  css  js  c++  java
  • [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;
        
    }
  • 相关阅读:
    子类父类拥有同名的方法时……
    大道至简第六章阅读感想
    大道至简第五章阅读感想
    java中子类与基类变量间的赋值
    继承与接口的使用
    产生10个随机数求和及一些产生随机数相关知识
    【文件处理】xml 文件 SAX解析
    【文件处理】xml 文件 DOM解析
    【文件处理】RandomAccessFile
    【Directory】文件操作(初识文件操作二)
  • 原文地址:https://www.cnblogs.com/evenbao/p/9689711.html
Copyright © 2011-2022 走看看