[hdu][1890][Robotic Sort]

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1890

伸展树,按照题意模拟,把所求第i个节点旋转至根节点,reverse一下

View Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

#define keytree root->ch[1]->ch[0]

using namespace std;

const int M = 100000+10;
const int inf = 0x3f3f3f3f;

struct node
{
    int size, rev, key;
    node *ch[2], *pre;
    void reverse()
    {
        if (size == 0)return ;
        rev ^= 1;
        swap(ch[0], ch[1]);
    }
    void update()
    {
        size = ch[0]->size + ch[1]->size + 1;
    }
    void pushdown()
    {
        if (rev) ch[0]->reverse(), ch[1]->reverse(), rev = 0;
    }
};

int arr[M];
node * hash[M];

class Splay
{
    public:
        node *root, *null;
        node *newnode(int var)
        {
            node *p;
            if (top) p = stk[top--];
            else p = &data[cnt++];
            p->key = var;
            p->size = 1;
            p->rev = 0;
            p->ch[0] = p->ch[1] = p->pre = null;
            return p;
        }
        void init()
        {
            top = cnt = 0;
            null = newnode(inf);
            null->size = 0;
            root = newnode(inf);
            root->ch[1] = newnode(inf);
            root->ch[1]->pre = root;
            root->update();
        }
        node *build(int l, int r)
        {
            if (l > r) return null;
            int mid = (l + r) >> 1;
            node *p = newnode(arr[mid]);
            hash[arr[mid]] = p;
            p->ch[0] = build(l, mid-1);
            p->ch[1] = build(mid+1, r);
            if (p->ch[0] != null)
                p->ch[0]->pre = p;
            if (p->ch[1] != null)
                p->ch[1]->pre = p;
            p->update();
            return p;
        }
        void maketree(int l, int r)
        {
            init();
            keytree = build(l, r);
            keytree->pre = root->ch[1];
            splay(keytree, null);
        }
        void rotate(node *x, int c)
        {
            node *y = x->pre;
            y->pushdown();
            x->pushdown();
            y->ch[!c] = x->ch[c];
            if (x->ch[c] != null)
                x->ch[c]->pre = y;
            x->pre = y->pre;
            if (y->pre != null)
                y->pre->ch[ y==y->pre->ch[1] ] = x;
            x->ch[c] = y;
            y->pre = x;
            y->update();
            if (y == root) root = x;
        }
        void splay(node *x, node *f)
        {
            x->pushdown();
            while (x->pre != f)
            {
                if (x->pre->pre == f)
                {
                    rotate(x, x->pre->ch[0] == x);
                    break;
                }
                node *y = x->pre;
                node *z = y->pre;
                int c = (y == z->ch[0]);
                if (x == y->ch[c])
                    rotate(x, !c), rotate(x, c);
                else
                    rotate(y, c), rotate(x, c);
            }
            x->update();
        }
        void select(int kth, node *x)
        {
            node * cur = root;
            while (true)
            {
                cur->pushdown();
                int tmp = cur->ch[0]->size;
                if (tmp == kth) break;
                else if (tmp < kth)
                    kth -= tmp + 1, cur = cur->ch[1];
                else cur = cur->ch[0];
            }
            splay(cur, x);
        }
        void reverse(int x, int y)
        {
            select(x-1, null);
            select(y+1, root);
            keytree->reverse();
        }
        int getans(int x, int y)
        {
            splay(hash[y], null);           // 第y个转换至根节点
            int ans = root->ch[0]->size;    // 求出数目
            reverse(x, ans);                // 反转一下
            return ans;
        }
    private:
        int cnt, top;
        node *stk[M], data[M];
}spt;

struct Num
{
    int x, y;
    bool operator < (const Num& a)const
    {
        if (x == a.x) return y < a.y;
        return x < a.x;
    }
}num[M];

int main()
{
    int n, a;
    while (~scanf("%d", &n) && n)
    {
        for (int i=1; i<=n; i++)
            scanf("%d", &a), num[i].x = a, num[i].y = i, arr[i] = i;
        sort(num+1, num+n+1);
        spt.maketree(1, n);
        for (int i=1; i<n; i++)
        {
            printf("%d ", spt.getans(i, num[i].y));
        }
        printf("%d\n", n);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/nigel0913/p/2581870.html