2017/7/29 离线赛 总结

来源:互联网 发布:mac qq下载 编辑:程序博客网 时间:2024/05/22 04:45

T1 UOJ136 键盘

    本着贪心的思想,我先斜着走到顶,然后直走到终点,显然这是最优的,但是我忽视了斜着走的最后一步可以和直着走的第一步合并, 我错误地把两个过程分开了。假如我当时多找几组数据来模拟说不定能找到这个错误,我也没敲个暴力来对拍(因为暴力太长了)。我得到的教训是:不能肯定自己算法的正确性是,不如敲个暴力对拍一下, 虽然可能花更长的时间,但总比没分好啊。

T2 51nod 最大字典序排列

    我敲的是O(n2)的,按照数据范围来讲只能过60分的数据,但是由于我在找到答案时立即break,并且数据也不卡,我还是得了80分。贪心的思路很容易想到,就是对于每个位置我们找最大能够到达该位置的数,我当时只想到O(n)地枚举。而正解是用线段树维护,当前点的个数和区间的最大值,每次查询时,找一个区间满足szk+1,然后求出最大值即可。

T3 计蒜客 机房网络

    考试的时候我算了算,500以内能够相对互质的数对有90000多对,我们只要dfs预处理每个点的子树里每个数的个数即可,然后乘一下就是知道该点通往父亲的边的对答案的贡献了,但这并没有什么卵用,当时我也没这么敲,因为这样只能过30分的数据,我换了种思路,然后直接TLE了。

    对于60分, 我们定义f(i)gcd=i的点对的传输时间之和, 那么答案就是f(1),那么如何求f(i)呢?对于i,我们可以将它的倍数的点看做关键点,则这些关键点间的gcd都为i的倍数,我们可以O(n)求出F(i)F(i)表示gcd=i的倍数的点对的运输时间之和),那么f(i)就是F(i)减去f(i)

    满分的话思路跟60分的一样,但是不用遍历所有的点,因为要用到的并不是全部的点,而且100000以内因子数最多的数只有128个因子,所以最多只要跑128个点,那么如何把这些点抽离出来呢?要用到虚树,就是把关键点连成一棵树,对于所有关键点,我们按dfs序从小到大大排序,然后再两两求LCALCA的求法有很多种,然而我只会两种,等下讲),将求出的LCA也加到这些点中,但不计入答案,最后我们要把1进去,因为造出来的虚树是两棵分开的树,需要一个公共的根,用栈便利虚树,求出每条边的贡献。对于求LCA有两种方案,挑重链和倍增,挑重链是我新学的,因此这里我讲一下挑重链的方法。 dfs一遍我们求出每个点的重儿子(子树规模最大的儿子),再rdfs一遍求出每条链的top,假如遍历到重儿子,那么top就延续下来,否则是重儿子本身。

总结

    重点是心态要放好,不能看到一道题目难就不写,这样会错过很多知识,比如T3让我学会了新的求LCA的方法。T2的话当时没仔细想, 想到用数据结构,但是不知道怎么实现,现在想想还是可以写的。

原创粉丝点击