[XezRound]不会有人不会吧

题目

题目描述
对于一个正整数序列 a 1 , a 2 , a 3 , … , a n a_1,a_2,a_3,\dots,a_n a1,a2,a3,,an,定义
V L = ∑ i = 1 n − L + 1 ( gcd ⁡ j = i j + L − 1 a j ) V_L=\sum_{i=1}^{n-L+1}\left(\gcd_{j=i}^{j+L-1}a_j\right) VL=i=1nL+1(j=igcdj+L1aj)
请求出 V 1 , V 2 , V 3 , … , V n V_1,V_2,V_3,\dots,V_n V1,V2,V3,,Vn

数据范围与提示
n ⩽ 1 0 6 n\leqslant 10^6 n106 1 ⩽ a i ⩽ 1 0 9 1\leqslant a_i\leqslant 10^9 1ai109

思路

最开始只会枚举因数 d d d,只能做到 O ( n A ) \mathcal O(n\sqrt{A}) O(nA ),太垃圾了……

事实上,有一个很神奇的性质:连续取 gcd ⁡ \gcd gcd 时,最多变化 log ⁡ A \log A logA 。所以我们应该把问题放在序列上考虑!

可以想到一个非常简单的方法是,移动右端点,同时维护左端点的若干等值段。加入一个数时,暴力修改这 O ( log ⁡ A ) \mathcal O(\log A) O(logA) 个等值段的值,合并同类项。对于 V V V 的贡献就用差分数组即可做到。又考虑到,一个等值段的值变化只有 O ( log ⁡ A ) \mathcal O(\log A) O(logA) 次,一共只会加入 O ( n ) \mathcal O(n) O(n) 个等值段,所以目标只是略去无效的变化。

然而这也极其简单:如果一个等值段,其值不会变化,则说明新加入的数是当前值的倍数;左边的等值段的值,是当前值的因数,自然也不会变化。

所以复杂度 O ( n log ⁡ A ) \mathcal O(n\log A) O(nlogA) 就做完了。竟然真的存在这样简单明快的做法,不可思议!

猜你喜欢

转载自blog.csdn.net/qq_42101694/article/details/121307092