zoukankan      html  css  js  c++  java
  • BZOJ1455: 罗马游戏

    【传送门:BZOJ1455


    简要题意:

      罗马皇帝很喜欢玩杀人游戏。 他的军队里面有n个人,每个人都是一个独立的团。最近举行了一次平面几何测试,每个人都得到了一个分数。 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻。他决定玩这样一个游戏。 它可以发两种命令: 1. Merger(i, j)。把i所在的团和j所在的团合并成一个团。如果i, j有一个人是死人,那么就忽略该命令。 2. Kill(i)。把i所在的团里面得分最低的人杀死。如果i这个人已经死了,这条命令就忽略。 皇帝希望他每发布一条kill命令,下面的将军就把被杀的人的分数报上来。(如果这条命令被忽略,那么就报0分)


    题解:

      左偏树的模版题

      左偏树就是合并堆

      性质:

      一、节点的关键值大于等于两个儿子节点的关键值(堆的性质)

      二、定义节点到最近的叶节点的距离为节点距离,任意节点的左儿子的距离大于右儿子的距离(左偏树的性质)

      左偏树在实现插入操作时总是从右侧插入,也就是总是让短的一侧生长,如果右侧长于左侧,那么交换左右侧,继续从右侧生长

      综上,都是hzwer(orz)的原话


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    using namespace std;
    int fa[1100000],l[1100000],r[1100000],dep[1100000],d[1100000];
    bool v[1100000];
    int findfa(int x)
    {
        if(x!=fa[x]) fa[x]=findfa(fa[x]);
        return fa[x];
    }
    int merge(int x,int y)
    {
        if(x==0) return y;
        if(y==0) return x;
        if(d[x]>d[y]) swap(x,y);
        r[x]=merge(r[x],y);
        if(dep[l[x]]<dep[r[x]]) swap(l[x],r[x]);
        dep[x]=dep[r[x]]+1;
        return x;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&d[i]);
        for(int i=1;i<=n;i++) fa[i]=i;
        memset(v,true,sizeof(v));
        dep[0]=-1;
        int m;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            char st[2];
            scanf("%s",st+1);
            if(st[1]=='M')
            {
                int x,y;
                scanf("%d%d",&x,&y);
                if(v[x]==false||v[y]==false) continue;
                int fx=findfa(x),fy=findfa(y);
                if(fx!=fy) fa[fx]=fa[fy]=merge(fx,fy);
            }
            else
            {
                int x;
                scanf("%d",&x);
                if(v[x]==false){printf("0
    ");continue;}
                int fx=findfa(x);
                printf("%d
    ",d[fx]);
                v[fx]=false;
                fa[fx]=merge(l[fx],r[fx]);
                fa[fa[fx]]=fa[fx];
            }
        }
        return 0;
    }

     

  • 相关阅读:
    MSSQL·阻止保存要求重新创建表的更改配置
    MSSQL·查询某数据库中所有表的记录数并排序
    异常处理·psftp·local unable to open
    MSSQL·Execution Timeout Expired. The timeout period elapsed prior to completion of the oper..
    MSSQL·ORDER BY 1 DESC是什么写法?
    MSSQL·大数据量历史数据清理的思路
    ubuntu清理wine卸载后的残余项目
    Learning the Vi Editor, 6th Edition O'Reilly Media
    做一粒不浮躁的好“种子”
    Qt Designer使用简易教程
  • 原文地址:https://www.cnblogs.com/Never-mind/p/7777304.html
Copyright © 2011-2022 走看看