其他分享
首页 > 其他分享> > 题解 CF1553F Pairwise Modulo

题解 CF1553F Pairwise Modulo

作者:互联网

题意

给定长度为 \(n\) 的数列 \(a\)。

定义 \(p_k = \sum_{1 \le i, j \le k} a_i \bmod a_j\)。你需要输出 \(p_1,p_2,\ldots,p_n\)。

\(2\le n\le 10^5\),\(1\le a_i\le 3\times 10^5\),保证 \(a\) 中的元素互不相同。


初步解法

首先看一眼应该能想到显然的 \(O(n\sqrt n\log n)\) 的做法。

我们从 \(1\) 到 \(n\) 计算 \(p_k\)。对于每个算到的 \(k\),我们只要计算 \(1,2,\ldots,k-1\) 与 \(k\) 之间产生的贡献。考虑正在计算 \(i(1\le i\le k-1)\) 与 \(k\) 的贡献。

总复杂度 \(O(n\sqrt n\log n)\)。提交上去!

\(\text{Time limit exceeded on pretest 7}\) \(\text{[pretests] }\)

优化解法

发现瓶颈是整除分块的 \(\sqrt n\),考虑把它替换掉。也就是考虑 \(a_k\bmod a_i(a_k>a_i)\) 的另一种算法。注意到正着做是 \(O(\sqrt n\log n)\),倒着却 \(O(\log^2 n)\)。那么能不能在计算 \(a_i\) 的时候就算好 \(a_k\) 呢?自然是可以的。

在计算 \(a_i\) 的时候,再用一个数据结构维护桶,与上面的方式类似,找到 \([a_i\times j,a_i\times(j+1)-1]\) 区间,容易发现这一段区间 \(a_i\) 的贡献是 \(-a_i\times j\),所以对这一段区间加上 \(a_i\times j\)。在到 \(a_k\) 时,查询一下 \(a_k\) 这个点的权值,在答案中减掉即可。

容易发现区间总个数仍然是 \(O(n\log n)\) 级别。这个数据结构要求支持区间加,单点查,还是树状数组即可。这部分的复杂度由 \(O(\sqrt n\log n)\) 优化到 \(O(\log^2 n)\)了。

\(\text{Accepted}\)

巨丑无比的代码:link。为了快速用了一个树状数组和一个线段树,主要内容在 main 函数中。

标签:le,log,树状,题解,bmod,sqrt,times,CF1553F,Pairwise
来源: https://www.cnblogs.com/irty/p/15048698.html