题面
对于长度为 l
且初始全为 0
的序列 a
(下标 1∼l
),有 q
次操作。操作分为两种:
- 给定 n,d,v
,对于每个满足 gcd(x,n)=d
的 x
,为 ax
加上 v
;
- 给定 x
,询问 i=1∑xai
。
数据范围:1≤l,q≤5×104, 1≤n,d,v≤2×105, 1≤x≤l
题目链接:HDUOJ 4947: GCD Array
分析
对于操作 1
,如果 d∤n
,则显然不可能满足
gcd(x,n)=d
。对于这样的情况我们忽略即可。
我们记 Δa(x)
代表某次进行第一种操作时位置 x
上值的增量,有:
Δa(x)==v⋅[gcd(x,n)=d]v⋅[gcd(dx,dn)=1]
借助莫比乌斯函数性质,有:
Δa(x)===k∣gcd(dx,dn)∑μ(k)⋅vk∣dx,k∣dn∑μ(k)⋅vk∣dn∑kd∣x∑μ(k)⋅v
我们注意到,kd∣x∑μ(k)⋅v
看起来十分类似莫比乌斯反演中的 F(n)
函数。既然如此,我们不妨考虑引入一个辅助数组 f
,使其满足:
a(x)=k∣x∑f(k)
由此一来,我们可以通过维护 f(x)
并通过莫比乌斯反演从而求得 a(x)
。
根据上面推导而来的式子,我们不难发现,操作一实则是对于 dn
的每一个因子 k
,向 f(kd)
中增加 μ(k)⋅v
。
而对于操作 2
:
i=1∑xa(i)==i=1∑xk∣i∑f(k)k=1∑x⌊kx⌋f(k)
整除分块搞一下就好了…… 由于分块需要快速求出区间和,所以可以考虑使用树状数组维护
f(x)
。
接下来我们简要分析一下复杂度:
对于操作 1
,dn
分解质因数的复杂度
O(N)
,加上树状数组单点更新后复杂度
O(NlogN)
;
对于操作 2
,整除分块复杂度
O(N)
,加上树状数组区间查询后复杂度
O(NlogN)
。
妙啊!
最后附上
我的代码
以供参考。
%%%