HDU-1512-Monkey King

来源:互联网 发布:国际贸易中心数据库 编辑:程序博客网 时间:2024/04/30 13:34

ACM模版

描述

描述

题解

典型的左偏树!

问题的核心是当两个猴子帮派中的大佬斗争之后,这两个大佬要强壮值减半并且两个帮派进行合并。那么涉及到的操作有优先队列的删除节点,优先队列的插入节点,优先队列的合并,因为普通的优先队列并不适合合并,所以这里采用左偏树比较合适。

给每个猴子建立一棵左偏树,不断进行合并,这样的话,插入节点的操作可以和优先队列的合并操作合在一起写,都看做优先队列的合并即可。

具体的看代码,很好理解。

代码

#include <iostream>#include <cstdio>using namespace std;const int MAXN = 1e5 + 10;struct node{    int key, dis;    int lson, rson;    int pre;} Tree[MAXN];int n, q;void init(int p, int k){    Tree[p].key = k;    Tree[p].pre = p;    Tree[p].lson = Tree[p].rson = 0;    Tree[p].dis = p == 0 ? -1 : 0;}int find(int x){    if (Tree[x].pre == x)    {        return x;    }    else    {        return find(Tree[x].pre);    }}int merge(int x, int y){    if (x == 0)    {        return y;    }    if (y == 0)    {        return x;    }    if (Tree[x].key < Tree[y].key)    {        swap(x, y);    }    Tree[x].rson = merge(Tree[x].rson, y);    int &ls = Tree[x].lson, &rs = Tree[x].rson;    Tree[ls].pre = Tree[rs].pre = x;    if (Tree[ls].dis < Tree[rs].dis)    {        swap(ls, rs);    }    if (rs == 0)    {        Tree[x].dis = 0;    }    else    {        Tree[x].dis = Tree[rs].dis + 1;    }    return x;}int del(int x){    int ls = Tree[x].lson;    int rs = Tree[x].rson;    Tree[ls].pre = ls;    Tree[rs].pre = rs;    Tree[x].dis = Tree[x].lson = Tree[x].rson = 0;    return merge(ls, rs);}int solve(int x, int y){    Tree[x].key >>= 1;    Tree[y].key >>= 1;    int _x = del(x), _y = del(y);    _x = merge(x, _x);    _y = merge(y, _y);    x = merge(_x, _y);    return Tree[x].key;}int main(int argc, const char * argv[]){    while (cin >> n)    {        int x;        for (int i = 1; i <= n; i++)        {            scanf("%d", &x);            init(i, x);        }        init(0, 0);        cin >> q;        int y;        while (q--)        {            scanf("%d%d", &x, &y);            int _x = find(x), _y = find(y);            if (_x == _y)            {                puts("-1");            }            else            {                printf("%d\n", solve(_x, _y));            }        }    }    return 0;}