LG P3327 [SDOI2015]约数个数和

Description

设 $d(x)$ 为 $x$ 的约数个数,给定 $n,m$,求

$$\sum_{i=1}^n\sum_{j=1}^md(ij)$$

Solution

有等式

$$d(ij)=\sum\limits_{x\mid i}\sum\limits_{y\mid j} [\gcd(x,y)=1]$$

证明:

如果 $ij$ 的因子 $k$ 中有一个因子 $p^c$, $i$ 中有因子 $p^a$, $j$ 中有因子 $p^b$。我们规定:

如果 $c\leqslant a$,那么在 $i$ 中选择。

如果 $c > a$,那么我们把 $c$ 减去 $a$,在 $j$ 中选择 $p^{c-a}$

对于 $ij$ 的因子 $k$ 的其他因子同理。于是对于任何一个 $k$ 有一个唯一的映射,且每一个选择对应着唯一的 $k$。

通过如上过程,我们发现:对于 $ij$ 的因子 $k=\prod {p_i}^{c_i}$,我们不可能同时在 $i$ 和 $j$ 中选择 $p_i$(优先在 $i$ 中选择,如果不够就只在 $j$ 中选择不够的指数),故 $x$ 和 $y$ 必须互质。

开始大力化简原式

\begin{align}
& \sum_{i=1}^n\sum_{j=1}^md(ij)\\
= & \sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{x\mid i}\sum\limits_{y\mid j} [\gcd(x,y)=1]\\
= & \sum\limits_{x=1}^n\sum\limits_{y=1}^m \left\lfloor\frac{n}{x}\right\rfloor \left\lfloor\frac{m}{y}\right\rfloor [\gcd(x,y)=1]\\
= & \sum\limits_{i=1}^n\sum\limits_{j=1}^m \left\lfloor\frac{n}{i}\right\rfloor \left\lfloor\frac{m}{j}\right\rfloor[\gcd(i,j)=1]
\end{align}

接下来莫比乌斯反演

设$f(x)=\sum\limits_{i=1}^n\sum\limits_{j=1}^m \left\lfloor\frac{n}{i}\right\rfloor \left\lfloor\frac{m}{j}\right\rfloor[\gcd(i,j)=x],g(x)=\sum_{x\mid d} f(d)$

整理得$g(x)=\sum\limits_{i=1}^{\frac{n}{x}}\sum\limits_{j=1}^{\frac{m}{x}} \left\lfloor\frac{n}{ix}\right\rfloor \left\lfloor\frac{m}{jx}\right\rfloor$

所以题目所求为$f(1)=\sum\limits_{1\mid d}\mu(\frac{d}{1})g(d)=\sum_{i=1}^n \mu(i)g(i)$

预处理$s(x)=\sum\limits_{i=1}^{x} \left\lfloor\frac{x}{i}\right\rfloor$,就可以$O(1)$计算$g$函数

时间复杂度$\Theta(T\sqrt{n})$

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long T,n,m,s[50005],mu[50005],prime[50005],tot,sum[50005],ans;
bool vst[50005];
inline int read()
{
    int f=1,w=0;
    char ch=0;
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        w=(w<<1)+(w<<3)+ch-'0';
        ch=getchar();
    }
    return f*w;
}
int main()
{
    for(int i=1;i<=50000;i++)
    {
        for(int j=1;j<=i;)
        {
            int k=i/(i/j);
            s[i]+=(k-j+1)*(i/j);
            j=k+1;
        }
    }
    mu[1]=1;
    for(int i=2;i<=50000;i++)
    {
        if(!vst[i])
        {
            prime[++tot]=i;
            mu[i]=-1;
        }
        for(int j=1;j<=tot&&i*prime[j]<=50000;j++)
        {
            vst[i*prime[j]]=true;
            if(!(i%prime[j]))
            {
                mu[i*prime[j]]=0;
                break;
            }
            else
            {
                mu[i*prime[j]]=-mu[i];
            }
        }
    }
    for(int i=1;i<=50000;i++)
    {
        sum[i]=sum[i-1]+mu[i];
    }
    T=read();
    for(;T;T--)
    {
        ans=0;
        n=read();
        m=read();
        for(int i=1;i<=min(n,m);)
        {
            int j=min(n/(n/i),m/(m/i));
            ans+=(sum[j]-sum[i-1])*s[n/i]*s[m/i];
            i=j+1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}
[SDOI2015]约数个数和】

 

posted @ 2020-10-09 08:09  QDK_Storm  阅读(146)  评论(0编辑  收藏  举报