【BZOJ2693】jzptab(莫比乌斯反演)
不妨先设\(n<=m\)。
把题目的柿子推一下:
由于\(lcm(i,j)*gcd(i,j)=ij\)
设\(d=gcd(i,j)\),我们枚举\(d\),提到最前面,再枚举\(i\)是\(d\)的几倍、\(j\)是\(d\)的几倍。
则在上面这个柿子中,\((d\times i)\)为原来的\(i\),\((d\times j)\)为原来的\(j\)。将分式化简,\(gcd(d\times i,d\times j)=d\)里同时约掉一个\(d\)得:
考虑到\(\sum_{i|n}\mu(i)=[n=1]\),代入\([gcd(i,j)=1]\)得:
我们再次枚举\(k\),提到\(\sum_{d=1}^n\)后:
考虑到\([k|gcd(i,j)]\)即为\([k|i,k|j]\):
这时我们先推另一个柿子:\(\sum_{i=1}^n[k|i]\),也就是询问\(1\)~\(n\)这些数中有多少个数是\(k\)的倍数,答案显然是\(\lfloor \frac{n}{k} \rfloor\)。
但如果是求\(\sum_{i=1}^ni[k|i]\)呢?
也就是吧所有\(1\)~\(n\)中所有是\(k\)的倍数的数加起来,答案显然就是$$1\times k+2\times k+...+\lfloor \frac{n}{k} \rfloor \times k=(1+2+...+\lfloor \frac{n}{k} \rfloor)\times k=\frac{(1+\lfloor \frac{n}{k} \rfloor)\times \lfloor \frac{n}{k} \rfloor \times k}{2}$$
把这个代入\((1)\)得
化简一下这个难看的柿子:
然后令\(T=dk\),我们枚举\(T\),并提到前面来。
令
那么显然,对于\(f(T)\),我们可以用数论分块做出来。
而对于\(g(T)\),由于\(\mu(\frac{T}{d})\)是积性函数,\(\frac{T^2}{d}\)是完全积性函数,所以\(g(T)\)也是积性函数。
那么对于\(g(T)\),我们在线性筛时分三种情况讨论:
-
\(T=p\),其中\(p\)为质数,那么我们再看回这个柿子:
\[g(T)=\sum_{d|T}\mu(\frac{T}{d})\times\frac{T^2}{d} \]明显,由于\(\mu\)的定义,所以当且仅当\(\frac{T}{d}=1\)或\(\frac{T}{d}=p\)时才能产生贡献,使\(\mu(\frac{T}{d})\ne0\)。
若\(\frac{T}{d}=1\),则\(T=d=p\),
\[\mu(\frac{T}{d})\times\frac{T^2}{d}=\mu(1)\times\frac{p^2}{p}=p \]若\(\frac{T}{d}=p\),又\(T=p\),则\(d=1\),
\[\mu(\frac{T}{d})\times\frac{T^2}{d}=\mu(p)\times\frac{p^2}{1}=-p^2 \]合并起来,即为
\[g(T)=\sum_{d|T}\mu(\frac{T}{d})\times\frac{T^2}{d}=p-p^2 \] -
\(T=i*p\),其中\(p\)为质数,\(i\ne1\)且\(i\%p \ne 0\),即\(gcd(i,p)=1\)。那么\(g(T)=g(i)\times g(p)\)
-
\(T=i*p\),其中\(p\)为质数,\(i\ne1\)且\(i\%p = 0\),即\(gcd(i,p)=p\),不妨设\(i=t\times p^k\)。
考虑推出:
\[g(p^k)=\sum_{d|{p^k}}\mu(\frac{p^k}{d})\times\frac{p^{2k}}{d} \]根据\(\mu\)的定义,当且仅当\(\frac{p^k}{d}=1\)或\(\frac{p^k}{d}=p\)时才能产生贡献,使\(\mu(\frac{p^k}{d})\ne0\)。
分情况讨论解得:
\[\]g(p^k) & =\sum_{d|{pk}}\mu(\frac{pk}{d})\times\frac{p^{2k}}{d}\
& =\mu(\frac{pk}{pk})\times \frac{p{2k}}{pk}+\mu(\frac{pk}{p{k-1}})\times\frac{p{2k}}{p{k-1}}\
& =pk-p
\end{aligned}\[ \]\[g(p^{k+1})=p^{k+1}-p^{k+2} \]由上述2式可得:
\[g(p^{k+1})=g(p^k)\times p \tag{2} \]则
\[\]g(T) & =g(i\times p)\
& =g(t\times p^k \times p)\
& =g(t)\times g(p^{k+1})\text{(\(t\)、\(p\)互质)}\
& =g(t)\times g(p^k)\times p\text{(结论(2))}\
& =g(t\times p^k)\times p\text{(\(t\)、\(p\)互质)}\
& =g(i)\times p
\end{aligned}\[ \]
最后的代码如下:
#include<bits/stdc++.h>
#define N 10000010
#define ll long long
#define mod 100000009
using namespace std;
int t,n,m,cnt;
ll prime[N],g[N],sum[N];
bool notprime[N];
void work()
{
int maxn=N-10;
g[1]=1;//记得初始化
for(int i=2;i<=maxn;i++)
{
if(!notprime[i])
{
prime[++cnt]=i;
g[i]=((i-1ll*i*i)%mod+mod)%mod;//第一种情况:T=p
}
for(int j=1;j<=cnt&&i*prime[j]<=maxn;j++)
{
notprime[i*prime[j]]=true;
if(!(i%prime[j]))
{
g[i*prime[j]]=g[i]*prime[j]%mod;//第二种情况:T=i%p且i%p=0
break;
}
g[i*prime[j]]=g[i]*g[prime[j]]%mod;//第三种情况:T=i%p且i%p!=0
}
}
for(int i=1;i<=maxn;i++)
sum[i]=(sum[i-1]+g[i])%mod;//维护前缀和
}
ll query(int n,int m)
{
ll ans=0;
for(int l=1,r=0;l<=n;l=r+1)//数论分块
{
r=min(n/(n/l),m/(m/l));
ll x=n/l,y=m/l;
ans=(ans+(((1ll+x)*x/2ll%mod)*((1ll+y)*y/2%mod)%mod)*(sum[r]-sum[l-1])%mod)%mod;
}
return ans;
}
int main()
{
work();//线性筛
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
if(n>m)swap(n,m);
printf("%lld\n",(query(n,m)%mod+mod)%mod);
}
return 0;
}