河南大学暑假集训的日常(2)
DAY3(并查集)
HDU - 1213 How Many Tables(并查集)
简单题。
代码:
1 |
|
HDU - 3038 How Many Answers Are Wrong(带边权并查集)
该题是一道时带边权的并查集。
对于每一个节点,不仅要维护它的祖先节点(若该节点上向右的区间有值的话右端点所对应的节点)的编号,还要维护该节点到它祖先节点的距离。
距离可以为负数,在计算区间的时候减去距离就行了。在对一组区间的数据检测是否合法的时候,检测两个端点是否可以通过某一种方式通过某一种路径联通,即两节点的祖先节点是否为同一节点。如果联通,那么就可以通过这两个节点到其祖先节点的距离来计算出这两个节点之间的距离了。
对于节点到其祖先节点的距离的维护,可以通过递归寻找祖先节点的过程中更新。在每一次寻找的过程中,如果该节点不是最终的祖先节点的话,那么将该节点到祖先节点的距离加上其父节点到祖先节点的距离。
对于新插入的节点,需要维护两节点的根节点的距离关系,可以通过画出向量的方式较为清楚的表达出来:
带边权并查集参考博客
代码:
1 |
|
POJ - 2492A Bug’s Life(种类并查集/拓展域并查集)
开两倍的f数组,x+n表示与x不相同的种类,(这种方法也叫作拆点)每一对虫子只需要保证性别不同即可,即x和y+n是联通的x+n和y也是联通的,但是x和y并不联通。如果在同一种类一侧出现了连接,即为产生了矛盾。
代码:
1 |
|
POJ - 1988 Cube Stacking(带边权并查集)
这道题同样也是带边权的并查集,有点像银河英雄传说这道题。每一个节点需要维护的值有到底部的距离和该栈的元素个数。核心部分还是在合并时权值的处理。
代码:
1 |
|
POJ - 1182食物链(拓展域并查集)
经典的拓展域并查集。
拓展域并查集:
首先对与最简单的并查集来说,如果两个是同一类,那么就p[pa]=pb对吧,但是对于两个相互排斥类的怎么办呢,这就涉及到拓展与并查集了,首先想法就是建立两个并查集,但是怎么把两个并查集联系起来呢?拓展个体。这里的拓展个体是什么意思呢,一个个体我们要拆成多个,比方说两个集合存在队立关系,那么对于一个个体a,我们假设存在一个个体a+n ,a和a+n这两个是处于对立关系的,所以当我们说a和b对立的时候,意思就是在说,a+n和b在同一并查集,b+n和a在同一并查集,当我们说,a和b是同类的时候,那么也就是说a和b属于一个并查集,且a+n和b+n属于一个并查集。
开三倍的数组,除了本身的域之外拓展的两个域表示域和本身的关系。分别表示天敌和捕食。
代码:
1 |
|
DAY4(树状数组)
POJ - 3468A Simple Problem with Integers(线段树/树状数组)
一个简单的区间修改和区间求和的板子题。
代码:
1 |
|
HDU - 1166敌兵布阵(树状数组)
单点修改区间求和的树状数组板子题。
代码:
1 |
|
HDU - 1394Minimum Inversion Number(逆序对/树状数组)
树状数组求逆序对数的改进版,需要在题中所给的序列生成的一系列序列中找到逆序对数最小的那一组。
关于求一个数列的逆序对数,可以用树状数组来维护一个数字前面比自己大的数的个数。树状数组可以方便的在线求前缀和,所以说可以用树状数组来完成这道题。
树状数组求逆序对参考博客
代码:
1 |
|
HDU - 2795Billboard(线段树)
这道题的实现其实不太难,难点是如何建树。
由题可知,我们可以在广告牌的高度上建树,然后对于每一个新的广告,查找最靠下的可以满足当前广告牌的位置插入,实际上就是维护了一个区间的最大值,来进行判断当前广告是否可以放到该区间中。
代码:
1 |
|
POJ - 2777Count Color(线段树+状态压缩)
用位运算来保存颜色的状态,加上懒惰标记,然后update维护父子节点的信息会不太一样。
代码:
1 |
|
河南大学暑假集训的日常(2)