hdu 1512 Monkey King 左偏树

来源:互联网 发布:软件项目管理教程 编辑:程序博客网 时间:2024/04/30 15:01

有这么一群猴子,他们喜欢打架,要是两个猴子没打过就会开打,打完后自己的val值减半,然后他们就变成好基友,他们之前各自的好基友

也变成了好基友,当两只猴子决斗时,并不一定是他们打,而是他们各自的好基友里面val值最大的出来打,如果他们本来就是好基友

那么就不打了,output  -1,否则output 打完后最大的val值:

利用左偏树求解,读入数据时为每一个猴子建立一颗左偏树,当两个猴子打架时,分别弹出root,然后打完,val减半,再将两个root和

剩下的左偏树进行合并:

#include <iostream>#include <cstdio>#include <cstring>#define N 1111111#define typec int         // type of key valusing namespace std;const int na = -1;int swap(int &x,int &y){    int t = x;    x = y;    y = t;}struct node{    typec key;    int l, r, f, dist,id;} tr[N];int iroot(int i)                // find i's root{    if (i == na) return i;    while (tr[i].f != na) i = tr[i].f;    return i;}int merge(int rx, int ry){    // two root: rx, ry    if (rx == na) return ry;    if (ry == na) return rx;    if (tr[rx].key < tr[ry].key)        swap(rx, ry);    int r = merge(tr[rx].r, ry);    tr[rx].r = r;    tr[r].f = rx;    if (tr[r].dist > tr[tr[rx].l].dist)        swap(tr[rx].l, tr[rx].r);    if (tr[rx].r == na) tr[rx].dist = 0;    else tr[rx].dist = tr[tr[rx].r].dist + 1;    return rx;                // return new root}int ins(int i, typec key, int root){    // add a new node(i, key)    tr[i].key = key;    tr[i].l = tr[i].r = tr[i].f = na;    tr[i].dist = 0;    return root = merge(root, i);  // return new root}int del(int i){    // delete node i    if (i == na) return i;    int x, y, l, r;    l = tr[i].l;    r = tr[i].r;    y = tr[i].f;    tr[i].l = tr[i].r = tr[i].f = na;    tr[x = merge(l, r)].f = y;    if (y != na && tr[y].l == i)        tr[y].l = x;    if (y != na && tr[y].r == i)        tr[y].r = x;    for ( ; y != na; x = y, y = tr[y].f)    {        if (tr[tr[y].l].dist < tr[tr[y].r].dist)            swap(tr[y].l, tr[y].r);        if (tr[tr[y].r].dist + 1 == tr[y].dist) break;        tr[y].dist = tr[tr[y].r].dist + 1;    }    if (x != na)        return iroot(x); // return new root    else return iroot(y);}node top(int root){    return tr[root];}node pop(int &root){    node out = tr[root];    int l = tr[root].l, r = tr[root].r;    tr[root].l = tr[root].r = tr[root].f = na;    tr[l].f = tr[r].f = na;    root = merge(l, r);    return out;}int add(int i, typec val)  // tr[i].key += val{    if (i == na) return i;    if (tr[i].l == na && tr[i].r == na && tr[i].f == na)    {        tr[i].key += val;        return i;    }    typec key = tr[i].key + val;    int rt = del(i);    return ins(i, key, rt);}int init(int n){    for (int i = 1; i <= n; i++)    {        scanf("%d", &tr[i].key); //%d: type of key        tr[i].l = tr[i].r = tr[i].f = na;        tr[i].dist = 0;        tr[i].id=i;    }}int main(){    int root = -1;    int a1,a2,a3,root1,root2;    int m,n,i;    while(scanf("%d",&n)==1)    {        init(n);        scanf("%d",&m);        for(i=0; i<m; i++)        {            scanf("%d%d",&a1,&a2);            root1=iroot(a1);            root2=iroot(a2);            if(root1==root2)            {                printf("-1\n");                continue;            }            else            {                node top1,top2;                top1=pop(root1);                top2=pop(root2);                tr[top1.id].key/=2;                tr[top2.id].key/=2;                top1.l = top1.r = top1.f = na;                top1.dist = 0;                top2.l = top2.r = top2.f = na;                top2.dist = 0;                root1=merge(root1,top1.id);                root1=merge(root1,top2.id);                root1=merge(root1,root2);                top1=top(root1);                printf("%d\n",top1.key);            }        }    }}

0 0
原创粉丝点击