hdu3031

题解:

左偏树模板题目

每一次合并,删除最大,修改最大

都是基本操作

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring> 
using namespace std;
const int M=105,N=1000005;
int T,n,m,p[M],root[M],v1=0,v0=0,c[N][2],dist[N],val[N],cnt;
void makeheap(int x,int v)
{
    c[x][0]=c[x][1]=dist[x]=0;
    val[x]=v;
}
int merge(int x,int y)
{
    if (!x||!y)return x+y;
    if (val[x]<val[y])swap(x,y);
    c[x][1]=merge(c[x][1],y);
    if (dist[c[x][0]]>dist[c[x][1]])swap(c[x][0],c[x][1]);
    dist[x]=dist[c[x][1]]+1;
    return x;
}
void ps(int &x){x=merge(c[x][0],c[x][1]);}
void change(int &x,int v)
{
    int k=merge(c[x][0],c[x][1]);
    makeheap(x,v);
    x=merge(x,k);
}
int main()
{
    scanf("%d",&T);
    while (T--)
     {
        cnt=0;
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)scanf("%d",&p[i]);
        memset(root,0,sizeof root);
        for (int i=1;i<=m;i++)
         for (int j=1,x;j<=p[i];j++)
          {
            scanf("%d",&x);
            makeheap(++cnt,x);
            root[i]=merge(root[i],cnt);
          }
        int x[2],rt[2];
        memset(rt,0,sizeof rt);
        memset(x,0,sizeof x);
        for (int i=1;i<=n;i++)
         {
            char s[2];
            int a;
            scanf("%s",&s);
            if (s[0]=='T')
             {
                scanf("%d",&a);
                rt[i&1]=merge(rt[i&1],root[a]);
                x[i&1]+=p[a];
             }
            if (s[0]=='C')
             {
                if (val[rt[0]]==val[rt[1]])continue;
                if (val[rt[0]]>val[rt[1]])
                 {
                    x[0]+=x[1];
                    x[1]=0;
                    rt[0]=merge(rt[0],rt[1]);
                    rt[1]=0;
                 }
                else
                 {
                    x[1]+=x[0];
                    x[0]=0;
                    rt[1]=merge(rt[1],rt[0]);
                    rt[0]=0;
                 }
             }
            if (s[0]=='L')
             {
                ps(rt[i&1]);
                x[i&1]--;
             }
            if (s[0]=='A')
             {
                scanf("%d",&a);
                change(rt[i&1],val[rt[i&1]]+a);
             }
            if (s[0]=='E')
             {
                scanf("%d",&a);
                change(rt[i&1],a);
             }
         }
        printf("%d:%d
",x[1],x[0]);
        if (x[1]>=x[0])v1++;
        else v0++;
     }
    if (v1<v0)puts("I will be back!!");
    else puts("Hahaha...I win!!");
    return 0;
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8066942.html