• WC2022 习题选做及总结


    1.Kitesurfing

    有一点神,结合了代码才理解到了它的精妙之处!

    考虑研究我们的解的形态,并尝试将其规范化。

    显然,我们的解当中必然存在一连串的大跳,然后接一段游泳小跳啥的,然后继续大跳啥的。

    假如中间只接了游泳,那么考虑将这段游泳和后面的大跳交换位置,发现最终落点不变,但中间落点不一定合法。

    如果中间落点不合法,则我们完全可以把部分游泳移动使之大跳落点恰好在岛屿的右边界。

    如果合法则递归考虑。

    假如中间直接了小跳,则小跳一定可以变大,让落点不变只需要让后面的跳跃同时缩短即可,发现这样做不仅会使答案不劣而且很有可能使它更优。

    由于小跳是小跳,因此这个小跳一定可以恰好落在岛屿的左端点。

    如果小跳和游泳同时连续存在,则小跳可以变大直到无游泳或大跳,则必然更优且划归为上述情况。

    整理以上讨论可以得到:

    存在最优解由以下结构构成:

    1.不断大跳,然后游一段泳,然后大跳到一个岛屿右端点。

    2.不断大跳,然后小跳到一个岛屿左端点,然后下一跳尽量跳远一点。

    于是我们可以通过上述规则转移。

    考虑对以每一个岛屿边缘为起点跳到以另一个岛屿的边缘为一次转移,由于最多只会有两种到达情况,因此总转移数是 \(O(n)\) 的,因此总复杂度是 \(O(n^2)\) 的。

    为了实现轻松,我们可以让每一个转移,即大跳过下一个岛屿也作为状态,把状态数升为 \(n^2\) ,会好写很多。

    官方题解说复杂度是 \(O(n^3)\) 的,但我觉得是 \(O(n^2log n)\) 的,但机房有人不信,有兴趣的同学可以精细实现。

    2.Date Pickup

    为什么这样的人也能有npy

    并不易于直接计算,答案显然具有单调性,不妨考虑二分答案 \(ans\)

    问题被转化成为了判断一个答案是否可行。

    考虑如果他在 \(a\) 时刻收到了电召该怎么办?考虑我们在一开始先计划前往点 \(x\) ,则满足 \(dis[s][x] + dis[x][t] \le a + ans\)

    于是我们想到去找到所有计划第一个到达的点。考虑到达了这样一个计划目标点之后怎么办?

    由于他刚走上一条边的时候也可能收到电召,因此一条边 \((u,v,w)\) 可以走当且仅当 \(w + dis[v][t] \le ans\) 。可以理解为刚下道就直奔 npy 家。

    考虑找到这些边,由于我们会先到目标点,所以我们可以用目标点吧这些可走的边扩展出来,于是就得到了可走的子图。

    检查这个子图是否有环以及最多能在里面逛多久。如果有环一直走环等电召,否则尽量走久一点,如果能挨到 \(b\) 以后则可行。

    注意到他可以在家摆烂摆到再不去就赶不上来自 npy 在 \(a\) 时刻的电召为止最优。

    我相信 Richard 的行为不值得提倡。

    3.Game Relics

    并不容易的题目。

    先考虑获得一些计算参数。如果我已经有了 \(k\) 种圣物,我继续抽奖直到抽到的花费。

    \[v_k = \frac{k}{2n} (2v_k + x) + \frac{n - k}{n} x \\ v_k = \frac{2n - k}{2n - 2k} x \]

    感性理解一下,我们先抽奖然后再买买买。决定买了之后就不会再抽。

    因此我们也可把买视作抽,因为最后始终会买干净。花费为剩余圣物花费平均数。

    注意到我抽到每个大小相同的圣物集合的概率是相等的。

    因此我们可以计算抽到 \(c_i\) 之和为 \(k\) 的圣物集合的概率,然后通过计算每种情况下的下一步决策的花费来计算期望,更容易计算。

    怎么说呢,相当神的一道题。

    4.新年的聚会

    我听钱老师讲课居然听懂了。

    如钱老师所言,内部无边的子图相当重要,因为我们可以用它去判断一坨点是否与另一坨点无边。

    先考虑一些简单的模型状况。比如说二分图。

    如果一个二分图的二部右边,则我们把每部点集分为两份,二部两两再比较是否有边,递归进行。容易发现,询问次数是 \(m \log n\) 级别的,\(m\) 是边数。

    于是再原图上我们也试图寻找独立集。同样考虑分治,先算左边的点的边,再算右边的点的边。

    发现把图分为一个点一个点的复杂度爆炸是因为第一步太多了,于是只要我们能控制两边独立集个数乘积复杂度及可保证。

    有一个构造方法可以把独立集划分个数限定到 \(\sqrt{m}\) 级别。及我们把度数大于 \(\sqrt{m}\) 点单独设为联通块(这样的点不超过 \(\sqrt{m}\) 个),然后剩下的点用染色的方式划分独立集(点度数不大于 \(\sqrt{m}\),由于是取mex,所以个数不超过 \(\sqrt{n}\) )。

    赶路

    我看懂了钱老师的一句话题解!

    钱老师:直接分治, solve(s, t, A) 表示 s 到 t 经过点集 A 里所有点。

    确实如此,随便选一个点,然后走另一边终点为该选中点,递归就好了。

  • 相关阅读:
    Web前端开发——HTML概述
    Web前端开发——概述
    [nowCoder] 两个不等长数组求第K大数
    [nowCoder] 两个长度相同有序数组的中位数
    [nowCoder] 完全二叉树结点数
    [nowCoder] 子数组最大乘积
    [nowCoder] 局部最小值位置
    [LeetCode] Binary Tree Right Side View
    [C/CPP系列知识] Type difference of character literals 和 bool in C and C++
    [C/CPP系列知识] C++中extern “C” name mangling -- Name Mangling and extern “C” in C++
  • 原文地址:https://www.cnblogs.com/Reanap/p/15854368.html
Copyright © 2020-2023  润新知