这是小豪巨巨开的LCA专题。题目的质量都是很好的。
比赛链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=72221#overview
密码:shuacm
A Checkers
题意:在一个直线上给你三个跳棋的一个状态,和另一种状态。求从一个状态到另一个状态的最近的步数。其中跳棋只能跳过一个子,且距离相等,不能重叠。
解法:1.标准解法:
首先,第一个特点是当你把三个跳棋缩在最短的时候,他们的状态是唯一。这样可以判断是否满足转移的条件。接下来,就是利用LCA求最短路径。这道题有个特点,模拟跳棋的过程就求GCD的过程。然后就可以利用这个性质二分答案求解。
2.我的奇葩解法:
这是我刷的第一道LCA,对LCA的印象就是树上操作。所以刚开始写的时候直接一层层建树了。结果就是爆栈了,因为是10^9。接下来写的时候我注意到建树的时候可以路径压缩建树,也就是变成有权值的边。这样接下来就是要讨论一下最后一步变化的方向,这样就可以得出解了。现在看自己的代码都觉得好恶心。
总结:这道题感觉就是练习代码能力的,顺便有LCA的思想。
B The merchant
题意:n个城市,由n-1条边组成一个树形。一种商品在每个城市有着不同的价格。求一个商人从一个城市到另一城市所能获得的最大收益。商人只能在一个地方买,在其之后的地方卖。
解法:这道题的思想是保存4个变量的值:Min[u],Max[u],Up[u],Down[u].
分别记录从当前点到LCA的最小,最大,上升收益,下降收益。其中的优化方法是根据他们的LCA高度来排序。这样可以充分利用的。下面已经求得的点来实现快速跳转.每次跳转控制在log(n)级别.
总结:这道题真是崩溃,因为完全不知道WA在哪。然后,自己写数据生成器,自己对拍,然后才找到自己的问题在哪里。
在随机建树的时候用到了并查集,感觉好神奇。
对拍:
@echo off
:loop
a.exe
b.exe
c.exe
fc data.out datame.out
if not errorlevel 1 goto loop
pause
goto loop
还有随机数生成的问题:
正常是 srand(time(NULL));
但是感觉这样其实不是很随机,所以可以利用自然溢出。改成srand(time(NULL)* time(NULL));这样更随机一点。
C Housewife Wind
题意:给你一棵树,两点之间有一个值。查询两个点之间的距离,带修改。
解法:dfs一遍得到遍历每个点的值。然后用BIT维护前缀和。
D A and B and Lecture Rooms
题意:一棵树上两个点,求到两个点之间距离相等点的个数。
解法:判断连个点的距离,如果是奇数无解。偶数在求出LCA的其余值。有个优化的地方是利用倍增的思想快速找到这个节点的父节点。
总结:对倍增的理解好了一些。