由于这个证明过程太过长。。。推荐大家看这个大佬的博文,我就是看这个学会的 http://www.cnblogs.com/chenyang920/p/4811995.html
原式 : G(n)=sigma(F(d)) (其中d|n,就是n%d==0)
反演公式: F(n)=sigma(U(n/d)*G(d))
原式 : G(n)=sigma(F(d)) (其中n|d,就是d%n==0)
反演公式: F(n)=sigma(U(d/n)*G(d)) (其中n|d) 这里U[x]的计算方式和上面的相同
因为最近遇到得多,总结一下。
最简单的就是直接套公式(一般是2式求gcd(x,y)==i的个数)就可以解决
就是设F(i)=sigema(1~n) gcd(x,y)==i 的个数,设G(i)=sigema(1~n) gcd(x,y)==i 的倍数 的个数
F(i)=sigema(1~n)d u(d/i)*G(d)
=sigema(1~n)d u(d/i)*(n/i)*(m/i)
通过分块加速达到O(sqrt(n))
对于一个积性函数f(i)
ans=sigema(1~n)x sigema(1~m)y f(gcd(x,y))
用先前的做法做
ans=sigema(1~n)i F(i)*f(i)
实际上这个看起来已经很优了,但是求枚举i和F(i)粗略看就已经两个sigema了,实际上跑出来应该是O(n^2),当然分块加速肯定会快(应该到O(n*sqrt(n)),然而有的题目为了卡这个专门出多组数据
总结出了一个公式,一般有
ans=sigema(1~n)k (n/k)*(m/k)* sigema(i|k)i f(i)*u(k/i)
推导过程:
ans=sigema(1~n)x sigema(1~m)y f(gcd(x,y))
ans=sigema(1~n)i F(i)*f(i)
代入反演公式2
ans=sigema(1~n)i f(i)* sigema(1~n)d u(d/i)*(n/d)*(m/d)
ans=sigema(1~n)i f(i)* sigema(1~n/i)d u(d)*(n/i/d)*(m/i/d)
设k=i*d
ans=sigema(1~n)i f(i)*sigema(1~n/i)d u(d)*(n/k)*(m/k)
ans=sigema(1~n)k (n/k)*(m/k)*sigema(i|k)i f(i)*u(k/i)
通过线性筛预处理出 sigema(i|k)i f(i)*u(k/i) 解决,带上前缀和分块加速的话时间大概就降低到每次询问O(sqrt(n))级别吧,朴素的题就直接套这个了。YY的GCD那题实际上也属于这一类,可以看作所有f都等于1嘛。然而某些题f值是要求的。。。这种题现在还没有A过。。。A过再说。。。
对于另一类类似sigema(1~n)i sigema(1~m)j i+j(gcd(i,j)==1)
有一个东西,就是sigema(d|p)u(d)等于1当且仅当p=1
那么上面这个式子就可以化成
sigema(1~n)i sigema(1~m)j (i+j)*sigema(d|i,d|j)u(d)
d提前变成sigema(1~n)d u(d)*(sigema(d|i)i sigema(d|j)j (i+j))