一类GCD统计问题

防发霉系列= =

暑假的时候学习(复习)了一下这一类GCD统计问题。。先是ORZ神犇。。

http://hi.baidu.com/__vani/item/3c1c789030f57cde1b49df45

。。大概就是这类问题了。。

。。贴几个模板题。。各有各的做法,各自有各自的优势。。


[Poi2007] Zap

快速求有多少正整数对x,y,满足x<=N,y<=M,并且gcd(x,y)=d。

暴力做复杂度O(NM)。

优化1、求x<=N/d,y<=M/d,gcd(x,y) = 1的数目,典型的Mobius反演。。即求Σ(N/i)*(M/i)*μ(i)。。复杂度O(N)

优化2、(N/i)*(M/i)最多只有根号级别的值。。求μ(i)的前缀和,合并一下即可做到O(sqrt(N+M))



Noi2010 能量采集 - 求Σ( gcd(x, y) ),(1 <= x <= n, 1 <= y <= m)。n, m <=10^5

枚举 GCD 然后依次反演必然会超时。

做法1、可以直接容斥。f[x] = (n/x*m/x) - Σf[i*x]。O(nlgn)

做法类似的题目,今年多校 Hdu 4675 GCD of Sequence。。

做法2、利用 N = Σphi(d) (d|N) 。。可以把原式变成 Σphi(d)*(N/d)*(M/d) (d<=min(N,M))。。线性筛欧拉函数 + 之前的技巧可以做到更快。。O(N)。



Spoj4491 - 询问 x <= n, y <= m的正整数对中有多少 gcd(x, y) 为质数?n, m<=10^7

对于每一个质数 p 答案是 Σ(N/pk)*(M/pk)*μ(k) ( 1<=k<=min(N/p,M/p) )  =  Σ(N/k)*(M/k)*μ(k/p) ( p<= k<=min(N,M) && p|k )。。

那么对所有质数的答案就是Σ(p∈P*)Σ(p<= k<=min(N,M) && p|k) (N/k)*(M/k)*μ(k/p)

直接的想法就是枚举质数然后分别反演。。O(N^1.5)

一个更优秀的算法是直接改变莫比乌斯反演中的miu函数。。即考虑一个miu(k)能贡献到多少个合式中。。

考虑miu(k),在 k 是 Square-Free-Number 的时候,miu(k) 的值为+-因子个数, k 中的因子中有且仅有一个指数为2的,miu(k)的值为+-1。。

然后复杂度就变成了预处理O(NlgN),每次查询O(sqrtN)。。(。。好像预处理可以做到O(N)。。?)

如果只有一次查询的话呢?暴力容斥也是可以的。


做法类似的题目,杭州网络赛 Hdu 4746 Mophues。。

这题问的不是质数了,问的是质因子个数小于等于 P 的。。首先 P 给那么大范围是毫无意义的。。因为最多就到 lgN,大概是20左右。。所以可以构造20个新莫比乌斯函数。。

可以通过一次O(NlgN)(。。也可以O(N)。。?)的预处理得到每个数的质因子以及重复质因子的数量。。假设有 A 个不同的质因子,重复的有 B 个,那这个数对质因子数为 B 到 B+A 的莫比乌斯函数都是有贡献的。。对J个质因子的莫比乌斯函数值的贡献是 C(A,J-B) 。。

然后预处理出莫比乌斯函数值 1~N 的前缀和 。。再预处理出前缀和 1~20 的前缀和。。

这样每次询问就可以在 O(sqrtN) 内完成了。。总复杂度O(NlgN + QsqrtN)。。不知道有没有更好的算法。。

你可能感兴趣的:(一类GCD统计问题)