【BZOJ2693】jzptab (莫比乌斯反演)

Description

给你$n$,$m$,求 $\sum^n_{i=1} \sum^m_{j=1} \ lcm(x,y)$

答案对$100000009$取模。

多组数据。

Input

第一行有一个正整数$t$表示数据组数

接下来$t$行每行有两个正整数$n$,$m$

Output

$t$行,第$i$行为第$i$组询问的答案。

HINT

对于$100\%$的数据:$t\leq 10000,n,m\leq {10}^7$

$100000009$不是一个质数。

 题解:

第一次打莫演,手推公式。(我为什么会做这道题)

\begin{aligned}
ans&=\sum^n_{i=1}\sum^m_{j=1}\frac{ij}{gcd(i,j)}\\
&=\sum^n_d\sum^n_{i=1}\sum^m_{j=1}\frac{ij}{d}[gcd(i,j)=d]\\
&=\sum^n_d\sum^{\lfloor\frac{n}{d}\rfloor}_{i=1}\sum^{\lfloor\frac{m}{d}\rfloor}_{j=1}\frac{d^2ij}{d}[gcd(i,j)=1]\\
&=\sum^n_d\sum^{\lfloor\frac{n}{d}\rfloor}_{i=1}\sum^{\lfloor\frac{m}{d}\rfloor}_{j=1}dij\sum_{k\mid gcd(i,j)}\mu(k)&(\sum_{d\mid n}\mu(d)=[n=1])\\
&=\sum^n_k\mu(k)\sum^n_d\sum^{\lfloor\frac{n}{d}\rfloor}_{i=1}[k\mid i]\sum^{\lfloor\frac{m}{d}\rfloor}_{j=1}[k\mid j]dij\\
&=\sum^n_k\mu(k)\sum^n_d\sum^{\lfloor\frac{n}{kd}\rfloor}_{i=1}\sum^{\lfloor\frac{m}{kd}\rfloor}_{j=1}dk^2ij\\
&=\sum^n_k\mu(k)\sum^n_d\sum^{\lfloor\frac{n}{kd}\rfloor}_{i=1}i\sum^{\lfloor\frac{m}{kd}\rfloor}_{j=1}j\cdot dk^2\\
&设 T=kd\\
ans&=\sum^n_{T=1}\sum^{\lfloor\frac{n}{T}\rfloor}_{i=1}i\sum^{\lfloor\frac{m}{T}\rfloor}_{j=1}j\sum_{d\mid T}\mu(\frac{T}{d})\frac{T^2}{d}
\end{aligned}

第一个部分 $ \sum^{\lfloor\frac{n}{T}\rfloor}_{i=1}i\sum^{\lfloor\frac{m}{T}\rfloor}_{j=1}j $ 用等差数列求和 $O(1)$ 求出

第二个部分 $ \sum_{d\mid T}\mu(\frac{T}{d})\frac{T^2}{d} $ 线性筛 $O(n)$ 预处理处

设$ g(x)=\sum_{d\mid T}\mu(\frac{T}{d})\frac{T^2}{d} $,考虑怎么求$g(x)$

如果说x为质数,那么根据公式$g(x)=x-x^2$

如果$x$不为质数,我们设$x=i\times p$,其中$p$为质数,那么有两种情况

$p\nmid i$,由于$i$和$p$互质而$g(x)$为积性函数,$g(x)=g(i\times p)=g(i)\times g(p)$

$p\mid i$,这个时候就有点不是很好搞了……

我们可以把i表示为$t\times p^k$($t$与$p$互质)

那么我们就尝试一下从乘了一个$p$会有什么影响这个方面来考虑一下

考虑$g(p^k)$的值,显然根据$\mu$的定义,只有$\mu(1)$和$\mu(p)$能够提供贡献(其他的$p$的指数都$>1$,所以都是$0$)

那么我们就可以得到$g(p^k)=f(1)p^k+f(p)p^{k-1}$

然后写出$g(p^{k+1})$的表达式,会发现是$f(1)p^{k+1}+f(p)p^k$

也就是说$g(p^{k+1})=g(p^k)p$

那么就可以得到$g(x)=g(i^p)=g(t\times p^k\times p)=g(t)\times g(p^k)\times p=g(x)\times p$

然后就可以顺利筛出来啦

最外层循环用数论分块,总时间 $O(\sqrt{n})$

CODE:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 
 5 #define mod 100000009LL
 6 #define N 10000005
 7 int t,n,m,cnt,ans;
 8 long long pri[N],g[N],sum[N];
 9 bool vis[N];
10 
11 void init(){
12     sum[1]=g[1]=1;
13     for(int i=2;i<N;i++){
14         sum[i]=1LL*i*(i+1)/2%mod;
15         if(!vis[i]){
16             g[i]=(i-1LL*i*i%mod+mod)%mod;
17             pri[++cnt]=i;
18         }
19         for(int j=1;j<=cnt&&i*pri[j]<N;j++){
20             vis[i*pri[j]]=true;
21             if(i%pri[j])
22                 g[i*pri[j]]=g[i]*g[pri[j]]%mod;
23             else
24                 g[i*pri[j]]=g[i]*pri[j]%mod;
25         }
26     }
27     for(int i=1;i<N;i++)(g[i]+=g[i-1])%=mod;
28 }
29 
30 int main(){
31     scanf("%d",&t);
32     init();
33     while(t--){
34         scanf("%d%d",&n,&m);
35         if(n>m)swap(n,m);
36         ans=0;
37         for(int i=1,pos=0;i<=n;i=pos+1){
38             pos=min(n/(n/i),m/(m/i));
39             ans+=sum[n/i]*sum[m/i]%mod*(g[pos]-g[i-1]+mod)%mod;
40             ans%=mod;
41         }
42         printf("%d\n",ans);
43     }
44 }
作者:ezoiLZH
本文版权归作者和博客园所有,欢迎转载,只要写明原文链接即可(^_^)。
posted @ 2018-07-30 19:57  ezoiLZH  阅读(315)  评论(0编辑  收藏  举报