首页 > 代码库 > HDU 3031 To Be Or Not To Be

HDU 3031 To Be Or Not To Be

题意:

n堆数字  m个操作  操作是两个人轮流执行  有5种操作  T操作拿一堆数字  C操作两个人比较自己手中最大的数字胜者得到对方的数字  L操作扔掉最大数字  A操作使最大数字加上一个值  E操作是最大数字改变值  两个人按上述规则进行R轮游戏  问每局游戏的比分和最后谁赢


思路:

要么是合并一堆数字  要么从一堆数字里拿最大  很明显这时可并堆的操作  想到使用左偏树


代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 2001000

int R,happy,wolf,n,m,tot;
int f[110],root[2],sum[110];
struct node
{
    int v,l,r,dis;
}nd[N];

int newnode(int x)
{
    nd[tot].v=x;
    nd[tot].l=0;
    nd[tot].r=0;
    nd[tot].dis=0;
    tot++;
    return tot-1;
}

int merge(int x,int y)
{
    if(!x) return y;
    if(!y) return x;
    if(nd[x].v<nd[y].v) swap(x,y);
    nd[x].r=merge(nd[x].r,y);
    if(nd[nd[x].l].dis<nd[nd[x].r].dis) swap(nd[x].l,nd[x].r);
    nd[x].dis=nd[nd[x].r].dis+1;
    return x;
}

int pop(int x)
{
    int tmp=merge(nd[x].l,nd[x].r);
    nd[x].dis=nd[x].l=nd[x].r=0;
    return tmp;
}

int main()
{
    int i,j,k,num;
    char op[10];
    while(~scanf("%d",&R))
    {
        happy=wolf=0;
        while(R--)
        {
            scanf("%d%d",&n,&m);
            tot=1;
            memset(f,0,sizeof(f));
            memset(sum,0,sizeof(sum));
            root[0]=root[1]=0;
            for(i=1;i<=m;i++) scanf("%d",&sum[i]);
            for(i=1;i<=m;i++)
            {
                for(j=1;j<=sum[i];j++)
                {
                    scanf("%d",&num);
                    f[i]=merge(f[i],newnode(num));
                }
            }
            for(i=1;i<=n;i++)
            {
                scanf("%s",op);
                if(op[0]=='T')
                {
                    scanf("%d",&k);
                    root[1&i]=merge(root[1&i],f[k]);
                    f[k]=0;
                    sum[(1&i)+105]+=sum[k];
                }
                else if(op[0]=='C')
                {
                    if(nd[root[0]].v>nd[root[1]].v)
                    {
                        root[0]=merge(root[0],root[1]);
                        sum[105]+=sum[106];
                        root[1]=0;
                        sum[106]=0;
                    }
                    else if(nd[root[0]].v<nd[root[1]].v)
                    {
                        root[1]=merge(root[0],root[1]);
                        sum[106]+=sum[105];
                        root[0]=0;
                        sum[105]=0;
                    }
                }
                else if(op[0]=='L')
                {
                    root[1&i]=pop(root[1&i]);
                    sum[(1&i)+105]--;
                }
                else if(op[0]=='A')
                {
                    scanf("%d",&k);
                    nd[root[1&i]].v+=k;
                }
                else if(op[0]=='E')
                {
                    scanf("%d",&k);
                    root[1&i]=pop(root[1&i]);
                    root[1&i]=merge(root[1&i],newnode(k));
                }
            }
            if(sum[105]>sum[106]) happy++;
            else wolf++;
            printf("%d:%d\n",sum[106],sum[105]);
        }
        if(happy>wolf) puts("I will be back!!");
        else puts("Hahaha...I win!!");
    }
    return 0;
}


HDU 3031 To Be Or Not To Be