题意:给你一个N,让你求∑i=1n∑j=1n∑k=1n∑l=1nlcm(gcd(i,j),gcd(k,l))
参考论文:贾志鹏线性筛
首先,考虑子问题,求这样一个东西:∑i=1n∑j=1n[(i,j)=d]
(中括号是一个函数:若其中的命题为真,返回1,否则返回0)
转化一下,就是求1到n/d两两之间互素的数然后再乘以d就是gcd为d的数了。
即:∑i=1n∑j=1n[(i,j)=d] = ∑、/123i=1n/d∑j=1n/d[(i,j)=1]
那么如题意所说,窝们可以定义一个函数 f(x)=∑、/123i=1x∑j=1x[(i,j)=1]
那么对于固定的n,窝们求gcd为x的个数为f(n/x)。
那么问题就变成了
ans=∑、/123i=1n∑j=1nlcm(i,j)*f(n/i)*f(n/j)
令p=gcd(i,j),则ans=∑p=1n∑i=1n/p∑j=1n/pp∗i∗j∗f(n/(i*p))∗f(n/(j*p))[(i,j)=1]
ans=∑p=1n∑i=1n/p∑j=1n/pp∗i∗j∗f(n/(i*p))∗f(n/(j*p))∑d|gcd(i,j)u(d)
=∑p=1n∑i=1n/p∑j=1n/pp∗i∗j∗f(n/(i*p))∗f(n/(j*p))∑d|i&&d|ju(d)
其中u(d)表示莫比乌斯函数,然后窝们想方设法将u(d)提到前面来:
=∑p=1n p*∑du(d)∑i=1n/p/d (i*d)*f(n/(i*d*p))∑j=1n/p/d (j*d)*f(n/(j*d*p))
可以将ij视为相同的两个东西,同时把d提出来放到前面:
=∑p=1n ∑du(d)*p*d*d*(∑i=1n/p/d i*f(n/(i*d*p)))2
然后,利用类似于参考论文中贾志鹏处理的方法,令t=p*d
=∑、/123t=1n(∑i=1n/t i*f(n/(i*t)))2* t*∑d|tu(d)*d
h(t)=t*∑d|tu(d)*d 是一个积性函数,窝们可以用线性筛的思想去O(n)的预处理出所有的h。
g(x)=∑i=1x i*f(x/i) 并不是一个积性函数但是x/i一共有大概sqrt(x)种取值。
在这里窝们可以用一种方法处理复杂度为sqrt(x),详细可以看代码。
那么ans=∑、/123t=1ng(n/t)2*h(t)
同理,n/t也是只有sqrt(n)种取值,所以复杂度最大也不超过sqrt(n)*sqrt(n)<=n,最后的复杂度不超过O(n)。
#include
#include
#include
#include
#include
#include
#include
#include
#include
ssfasdfasdfasdfasdfasdf