AT 1506
前言
赛时小丑以为写假了,遂写篇题解。
我不强,我不知道调和级数,但我会根号做法。
题意
求 ∑i=1N−1∑j=i+1N⌊min(Ai,Aj)max(Ai,Aj)⌋。
做法
显然可以先将 A 从小到大排序,然后答案就变成了 ∑i=2N∑j=1i−1⌊AjAi⌋。
然后这就是一个经典的整除分块。具体的,先枚举 Ai,那此时 ⌊AjAi⌋ 的答案只有 O(V) 种。对于当前的 k=⌊AjAi⌋,可以求出 ⌊AnxtAi⌋=k 的另一个边界 nxt,然后直接跳到 nxt−1 即可。由于 k 的取值只有 O(V) 种,找到 nxt 的过程可以使用二分答案,于是复杂度就是 O(n×V×log2n)。
放个代码。赛时代码比较丑,二分答案就不要细看了。
然而这样是需要在 2s 内跑 4×109 的。明显会 TLE。思考如何优化。
发现整除分块不好优化,所以尝试将 log2n 优化掉。发现二分答案的值域只有 O(V),所以可以开一个数组提前预处理。时间复杂度为 O(n×V+V×log2n)。
总结
时间复杂度为 O(n×V+V×log2n),相比其他做法的却劣了不少,需要 1600ms+。
赛时真是小丑,同时感谢 _maojun_。