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;
    }

     

  • 相关阅读:
    手势模型和Angular Material的实现
    拟物设计和Angular的实现
    深入探索AngularJS
    自己动手做Web框架—MVC+Front Controller
    学习《CSS选择器Level-4》不完全版
    【基础】固定列宽的表格及示例演示
    使用min-content实现容器宽度自适应于内部元素
    【基础】CSS实现多重边框的5种方式
    【图片版】学习CSS网格布局
    【基础】EM 还是 REM?这是一个问题!
  • 原文地址:https://www.cnblogs.com/Never-mind/p/7777304.html
Copyright © 2011-2022 走看看