【题解】牛客练习赛60
A.大吉大利
我们按位考虑,那么每一位的贡献就是在二进制下这一位在个数中出现的次数的平方乘上二进制的系数。
B.三角形周长和
也是一道签到题,但是边长改成了曼哈顿距离,至于为什么,完全是因为我不想写std去判精度。
因为是1000,所以直接去枚举所有边,那么每一条边显然会在其他个三角形中出现,这个就是这条边的贡献系数,这题就算完了。
C.操作集锦
求长度为的字符串的长度为的子序列。我们考虑用表示考虑前个字符形成的长度为的子序列个数。
那么如果我们不考虑会重复的情况,转移方程是。
那么显然是多算一部分重复的,我们记录表示这个字符之前出现的位置,那么多算的这部分很容易发现就是。
D.斩杀线计算大师
算是出了一道假题,正解应该是同余最短路。介绍一下做法吧,现在是要求,那么我们设,那么显然我们只需要凑出就行了,考虑到是的余数。因此的取值范围是。那么我们不妨设表示用可以凑出的最小的数。不难发现
,。如果我们对每个下标都对取模,可以发现转移变成了以及。容易发现这恰好是最短路的转移,因此我们用的每个数作为数组下标,然后去跑最短路就能得到合法的方案。注意在跑最短路的时候记录路径的转移,这样就能通过去求解答案。复杂度是。
额,这道假题应该是源于我图论实在是太差了,导致很多图论的做法都没有了解过。
E.旗鼓相当的对手
或者长链剖分应该都可以做。我写的std是用的。因为是查询节点不同子树中距离为的点对,因此我们只需要用一个数组来记录某个点的深度值,那么每次询问相当于查询所有深度为的其他子树的节点产生的贡献。
感觉实在是非常的裸,所以难点在于,有其他疑问可以提出来。
F.几何带师
总的来说这题我是要谢罪的。因为三点不共线的话,用std的做法有产生精度误差,其实可以避免这个精度误差,但是码量会比较大,因此我花了一天时间去造不存在三点共线的数据。
最后虽然找到了一个方法,但是在写数据生成器的时候,没有判重点,因此数据中存在重点。又因为的数据是难以验证是否存在三点共线的,因此我就用纯暴力去和std对跑,然后所有数据都通过了,这是我没有想到的,在std和暴力对上的情况下,我就相信了数据中是不存在重点的。不过还好是最后一题,没有影响排名。下面讲一下做法。
我们已经两个定点,现在我们需要判断直线是否和线段相交。现在我们考虑一下在同侧的情况。那么必定存在在或者在中。
我们就假设在中好了,设和分别表示和的角度。设和分别表示和。那么在中当且仅当且。不难发现这是一个二维偏序,我们对其中一维排序然后用统计即可。
当满足异侧的时候,则是两个外角满足大小关系,画图可以很容易发现。