A - ReLU
输入,输出。
B - Billiards
假设向点((x, 0))处踢符合条件,此时根据反射角相等可以得到(frac{S_y}{x - S_x} = frac{G_y}{G_x - x}),解得(x = frac{S_x cdot G_y + S_y cdot G_x}{G_y + S_y})。
C - Travel
利用std里的next_permutation
函数枚举所有排列,然后模拟就完事了。
D - Water Heater
把人看成两个操作,在(S_i)时执行(sum = sum + p_i),在(T_i)时执行(sum = sum - p_i)。
注意到时间的值域为([0, 2 imes 10^5]),所以可以扫一遍时间,把当前时刻发生的操作执行完之后判断一下就完事了。注意要先删再加。
如果存在某个时间(sum)大于(W),则输出NO,否则输出YES。
E - Queen on Grid
很明显的一道DP题。
记(dp_{i, j})为从((1, 1))走到((i, j))的方法数。则(dp_{i, j})可以从三个方向转移过来:左,上,左上。如果枚举每个方向,然后暴力扫一遍这个方向上直至遇到墙的所有点,用这些点来更新当前点,那么就可以得到一个(O(n^3))的DP。
很明显,这个复杂度在这题的数据量下会TLE,所以需要再优化一下。
利用前缀和的思想去优化就可以将这题优化到(O(n^2))。
F - Confluence
题面明示了这题并查集。
为每个节点开一个map,map[id]表示以这个点为代表节点的集合中,(id)班的学生数量。
在并查集merge
操作的时候,可能会合并两个集和,这个时候只需要合并两个代表节点的map,就可以得到合并之后的结果。
但是有一个问题就是暴力合并的话时间复杂度会被卡到(O(n^2))。比如构造数据,从左至右不断合并,这个时候的时间复杂度就是(sum_{i = 1}^{n - 1}i = O(n^2))。
利用启发式合并去优化,既每次merge
的时候,总是将较小的那个集和合并到另外一个集和,这样时间复杂度可以优化到(O(n log n))。