zoukankan      html  css  js  c++  java
  • HDU 1512 Monkey King

    HDU_1512

        这个题目用左偏树做的居多,昨天晚上突然想到其实用一棵splay也能方便的实现合并的操作,于是就用splay写了。

        在fight之前,要先找到两棵树中的最大值,然后splay到根部并修改。之后为了实现合并,可以将一棵splay“最右边”的元素splay到根部,这样根的右子树就为空了,直接把另一棵树放到这个位置即可。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 100010
    #define INF 0x7fffffff
    int N;
    struct Splay
    {
        int pre, ls, rs, key, max;
        void update(); void zig(int ); void zag(int ); void splay(int );
        void renew()
        {
            pre = ls = rs = 0;
        }
    }sp[MAXD];
    int Max(int x, int y)
    {
        return x > y ? x : y;
    }
    void Splay::update()
    {
        max = Max(Max(sp[ls].max, sp[rs].max), key);
    }
    void Splay::zig(int x)
    {
        int y = rs, fa = pre;
        rs = sp[y].ls, sp[rs].pre = x;
        sp[y].ls = x, pre = y;
        sp[y].pre = fa, sp[fa].rs == x ? sp[fa].rs = y : sp[fa].ls = y;
        update();
    }
    void Splay::zag(int x)
    {
        int y = ls, fa = pre;
        ls = sp[y].rs, sp[ls].pre = x;
        sp[y].rs = x, pre = y;
        sp[y].pre = fa, sp[fa].rs == x ? sp[fa].rs = y : sp[fa].ls = y;
        update();
    }
    void Splay::splay(int x)
    {
        int y, z;
        for(; pre != 0;)
        {
            y = pre;
            if(sp[y].pre == 0)
                sp[y].rs == x ? sp[y].zig(y) : sp[y].zag(y);
            else
            {
                z = sp[y].pre;
                if(sp[z].rs == y)
                {
                    if(sp[y].rs == x)
                        sp[z].zig(z), sp[y].zig(y);
                    else
                        sp[y].zag(y), sp[z].zig(z);
                }
                else
                {
                    if(sp[y].ls == x)
                        sp[z].zag(z), sp[y].zag(y);
                    else
                        sp[y].zig(y), sp[z].zag(z);
                }
            }
        }
        update();
    }
    void init()
    {
        int i;
        sp[0].max = -INF;
        for(i = 1; i <= N; i ++)
        {
            sp[i].renew();
            scanf("%d", &sp[i].key);
            sp[i].max = sp[i].key;
        }
    }
    int findmax(int cur, int v)
    {
        if(sp[cur].key == v)
            return cur;
        if(sp[sp[cur].ls].max == v)
            return findmax(sp[cur].ls, v);
        else
            return findmax(sp[cur].rs, v);
    }
    int findlast(int cur)
    {
        if(sp[cur].rs)
            return findlast(sp[cur].rs);
        else
            return cur;
    }
    int romax(int x)
    {
        int t = findmax(x, sp[x].max);
        sp[t].splay(t);
        return t;
    }
    int rolast(int x)
    {
        int t = findlast(x);
        sp[t].splay(t);
        return t;
    }
    int findroot(int x)
    {
        for(; sp[x].pre != 0; x = sp[x].pre);
        return x;
    }
    void fight(int x, int y)
    {
        int tx, ty, t;
        tx = findroot(x), ty = findroot(y);
        if(tx == ty)
            printf("-1\n");
        else
        {
            tx = romax(tx), ty = romax(ty);
            sp[tx].key /= 2, sp[tx].update();
            sp[ty].key /= 2, sp[ty].update();
            t = rolast(tx);
            sp[t].rs = ty, sp[ty].pre = t;
            sp[t].update();
            printf("%d\n", sp[t].max);
        }
    }
    void solve()
    {
        int i, x, y, m;
        scanf("%d", &m);
        for(i = 0; i < m; i ++)
        {
            scanf("%d%d", &x, &y);
            fight(x, y);
        }
    }
    int main()
    {
        while(scanf("%d", &N) == 1)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    深度学习调参笔记(trick)
    Linux调用Kaggle API下载数据
    Jupyter Notebook 入门指南
    ondyari / FaceForensics配置指南
    python读写文件
    Federated Learning with Matched Averaging
    Advances and Open Problems in Federated Learning
    使用标准输入对话框
    各类位置信息
    标准对话框的使用
  • 原文地址:https://www.cnblogs.com/staginner/p/2552488.html
Copyright © 2011-2022 走看看