题目链接 Problem Link

题意:

给定一个正整数 \(N(N\le2^{31}-1)\)

\(ans_1=\sum_{i=1}^n\varphi(i)\)

\(ans_2=\sum_{i=1}^n \mu(i)\)

前置芝士

  1. \(\mu(p)=-1\) (\(p\)为质数)
  2. \(\mu(i*p_j)=\mu(i)*(-1)\) (\(p_j\)为质数且 \(i \ge 1\)\(i \%p_j >0\))
  3. \(\mu(i*p_j)=0\) \((p_j\)为质数且 \(i \ge 1\)\(i \%p_j =0\))
  4. \(\varphi(p)=p-1\) (\(p\)为质数)
  5. \(\varphi(i*p_j)=\varphi(i)*(p_j-1)\) (\(p_j\)为质数且 \(i \ge 1\)\(i \%p_j >0\))
  6. \(\varphi(i*p_j)=\varphi(i)*p_j\) \((p_j\)为质数且 \(i \ge 1\)\(i \%p_j =0\))
  7. 这两个函数的线性筛法
  8. 它们都是积性函数,即 \(\varphi(i)*\varphi(j)=\varphi(i*j) , \mu(i)*\mu(j)=\mu(i*j)\)

先来证两个东西

\((1)\) \(\sum _{d|n}{\varphi(\frac nd)}=n\)

证明:我们要证明的是\(\sum _{d|n}{\varphi(\frac nd)}=n\), 因为在 \(d|n\) 的条件下 \(\frac nd\)\(d\) 对称,所以原命题变为 \(\sum _{d|n}{\varphi(d)}=n\)

\(n=1\) 时,命题显然成立

\(p\) 为质数,当 \(n=p\) 时,显然成立,因为 \(\sum_{d|p} \varphi (d)=\varphi(p)+\varphi(1)=p-1+1=p\)

显然对 \(n=p^q\) 也成立,证明:
\[
\sum_{d|p^q} \varphi(d)=\varphi(1)+\varphi(p)+\varphi(p^2)+…+\varphi(p^q)=\sum _{i=0}^{q}{\varphi {(p^i)}}=1+\sum _{i=1}^{q}{\varphi {(p^i)}}
\]

根据 \(\varphi(p^k)=p^k-p^{k-1}=(p-1)*p^{k-1}\) \((p\)为质数\()\)
\[
=1+\sum _{i=1}^{q}{\varphi {(p^i)}}=1+\sum_{i=0}^{q-1}{p^q*(p-1)}
\]

根据等比数列求和公式
\[
=1+(p-1)*\frac {1-p^q}{1-p}=p^q
\]

所以 \(\sum_{d|p^q} \varphi(d)=p^q\) \((p\)为质数\()\)

然后,我们定义函数 ,\(F(n)=\sum_{d|n}\varphi(d)\),也就是说 \(F(p^k)=\sum _{d|p^k}\varphi (d)\)\(F(p^k)\) 显然为积性函数,\(p\) 为质数

证明:
\[
F(p_1^n)*F(p_2^m)=\sum_{i|p_1^n}\varphi(i)*\sum_{j|p_2^m}\varphi(j)=\sum_{i|p_1^n}\sum_{j|p_2^m}\varphi(i)*\varphi(j)
\]

我们假设 \(p_1\) 不等于 \(p_2\) ,那么因为 \(gcd(p_1,p_2)=1\),所以 \(gcd(p_1^a,p_2^a)=1\)

于是在上面的柿子中,\(gcd(i,j)=1\),所以 \(\varphi(i)*\varphi(j)=\varphi(i*j)\)

所以
\[
F(p_1^n)*F(p_2^m)=\sum_{i|p_1^n}\sum_{j|p_2^m}\varphi(i*j)=\sum_{d|p_1^n*p_2^m}\varphi(d)=F(p_1^n*p_2^m)
\]

然后,因为整数唯一分解定理,一个正整数可以被分解为 \(p_1^{b_1}*p_2^{b_2}*…*p_k^{b_k}\) 的形式,\(p\) 为质数,那么
\[
F(n)=F(p_1^{b_1}*p_2^{b_2}*…*p_k^{b_k})=F(p_1^{b_1})*F(p_2^{b_2})*…*F(p_k^{b_k})=p_1^{b_1}*p_2^{b_2}*…*p_k^{b_k}=n
\]

所以
\[
\sum_{d|n}\varphi(d)=n
\]

因为, \(n\)为任何正整数时都成立,所以原命题成立

\((2)\) \(\sum _{d|n} \mu(d) = \left\{\begin{aligned} 1 & (n=1)\\ 0 & (n\ne1) \end{aligned}\right.\)

\(n=p_1^{b_1}*p_2^{b_2}* … * p_k^{b_k} , m=p_1*p_2* … *p_k\)
\[
\sum_{d|n}\mu(d)=\sum_{i=1}^{b_1}\mu(p_1i)+\sum_{i=1}^{b_2}\mu(p_2^i)+…\sum_{i=1}^{b_k}\mu(p_k^i)
\]

\[
=\mu(p_1)+\mu(p_2)+…+\mu(p_k)+\sum_{i=2}^{b_1}\mu(p_1i)+\sum_{i=2}^{b_2}\mu(p_2^i)+…\sum_{i=2}^{b_k}\mu(p_k^i)
\]

\[
=m+0+0+…+0=m=\sum_{d|m}{\mu(d)}
\]

然后你就看每一个项有多少个质数乘起来,由于质数互不相同,

所以可以套用二项式定理和前置芝士第二条来做
\[
\sum_{d|n}\mu(d)=\sum_{d|m}{\mu(d)}=\sum_{i=0}^kC^i_k*(-1)^i=(1+(-1))^k
\]

\(k>0\) 的时候显然为 \(0\) ,证明了 $\sum _{d|n}\mu(d)=0 $ \((n \ne 1)\)

\(k=0\) 的时候,\(n\) 就为 \(1\) ,直接代入 \(\sum_{d|n}\mu(d)\) 就可知答案为 \(1\) ,证明了 $\sum _{d|n}\mu(d)=1 $ \((n = 1)\)

于是原命题成立

好,证明正式开始

先说一个叫做狄利克雷卷积的东西

我们定义函数 \(f\) , \(g\) 的狄利克雷卷积为 \((f*g)(i)\)

\((f*g)(i)=\sum_{d|i}f(d)*g(\frac id)\)

我们设 \(S(n)=\sum _{i=1}^n{f(i)}\),也就是函数的前缀和
\[
\sum_{i=1}^{n}(g*f)(i)=\sum_{i=1}^n(\sum_{d|i}{g(d)*f(\frac id)} )
\]

然后跟 #1\(60\) 分做法类似,把它变一变,变成枚举约数 \(d\)
\[
=\sum_{d=1}^n(g(d)*\sum_{i=1}^{\lfloor \frac nd \rfloor}{f(i)} )
\]

\(S(i)\) 替换后面那个 \(\sum\)
\[
=\sum_{d=1}^ng(d)*S(\lfloor \frac nd \rfloor)
\]

然后我们要用移项大法:

\[
0=\sum_{i=1}^{n}(g*f)(i)-\sum_{i=1}^{n}(g*f)(i)
\]

\[
0=\sum_{i=1}^{n}(g*f)(i)-\sum_{d=1}^ng(d)*S(\lfloor \frac nd \rfloor)
\]

\[
0=\sum_{i=1}^{n}(g*f)(i)-\sum_{d=2}^ng(d)*S(\lfloor \frac nd \rfloor)-g(1)*S(n)
\]

\[
g(1)*S(n)=\sum_{i=1}^{n}(g*f)(i)-\sum_{d=2}^ng(d)*S(\lfloor \frac nd \rfloor)
\]

此时,\(S(n)\) 就出现了

然后我们代入欧拉函数,

\(f(i)=\varphi(i) , g(i)=1\)
\[
\sum_{i=1}^n\varphi(i)=1*S(n)=\sum_{i=1}^{n}(g*f)(i)-\sum_{d=2}^n 1*S(\lfloor \frac nd \rfloor)
\]

我们再来看一下狄利克雷卷积的定义:
\[
\sum_{i=1}^{n}(g*f)(i)=\sum_{i=1}^n(\sum_{d|i}{g(d)*f(\frac id)} )
\]

\[
=\sum_{i=1}^n(\sum_{d|i}f(\frac id) )
\]

我们知道 \(\sum _{d|i}{\varphi(\frac id)}=i\)

所以
\[
\sum_{i=1}^{n}(g*f)(i)=\sum_{i=1}^ni= \frac {n*(n+1)}{2}
\]

把这个结果回代上面的柿子

\[
g(1)*S(n)= \frac {n*(n+1)}{2}-\sum_{d=2}^n g(d)*S(\lfloor \frac nd \rfloor)
\]

\[
S(n)= \frac {n*(n+1)}{2}-\sum_{d=2}^n S(\lfloor \frac nd \rfloor)
\]

好,这个可以递归求了,其中,后面那个 \(\sum\) 可以 \(O(\sqrt {n})\) 来求

我们先来运行一下这段代码

int n=30;
for(int d=1;d<=n;++d)
    printf("%d ",n/d*d);

输出结果为:

30 15 10 7 6 5 4 3 3 3 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

观察一下会发现相同的数很多,而且都堆在一起

这里有个性质,以 \(l\) 为左端点的相同的数的区间的右端点是 \(\lfloor \frac n{\lfloor \frac nl \rfloor} \rfloor\)

证明:

对于任意一个 \(l(l\le n)\),我们需要找到一个最大的 \(r(l \le r \le n)\),使得 \(\lfloor \frac nl \rfloor=\lfloor \frac nr \rfloor\).
\[
\lfloor \frac nl \rfloor \le \frac nl
\]

\[
\lfloor \frac n{\lfloor \frac nl \rfloor} \rfloor \ge \lfloor \frac n{\frac nl} \rfloor=\lfloor l \rfloor=l
\]

\[
l \le \lfloor \frac n{\lfloor \frac nl \rfloor} \rfloor
\]

所以 \(r=\lfloor \frac n{\lfloor \frac nl \rfloor} \rfloor\)

代码大约就是

for(int l=1,r;l<=n;l=r+1)
{
    r=n/(n/l);
    reg int now=n/l; // 区间内的数的值
   // do something ...
}

这个复杂度姑且可以认为是 \(O(\sqrt n)\)

那么对于欧拉函数,在 \([l,r]\) 中的答案就是

\[
(r-l+1)*S(\lfloor\frac nl \rfloor)
\]

把这堆 \(l,r\) 的答案加起来,再用 \(\frac {n*(n+1)}{2}\) 减去后就是 \(S(n)\)

先线性筛预处理出 \(S(1\) ~ \(1000000)\),然后记忆化搜索,开个 \(map\) 或者蛤希存 \(S(i)\) 的结果,当然如果 \(i \le 1000000\) 就直接查表

莫比乌斯函数也差不多,这里 \(S(n)=\sum_{i=1}^n\mu(i)\)

用狄利克雷卷积

\(f(i)=\mu(i) , g(i)=1\),那么
\[
\sum_{i=1}^n{(g*f)(i)}=\sum_{i=1}^n\sum_{d|i}g(d)*f(\frac id)
\]

\[
=\sum_{i=1}^n\sum_{d|i}\mu(\frac id)=\sum_{i=1}^n\sum_{d|i}\mu(d)=1+\sum_{i=2}^n0=1
\]

我们已经知道,

\[
g(1)*S(n)=\sum_{i=1}^{n}(g*f)(i)-\sum_{d=2}^ng(d)*S(\lfloor \frac nd \rfloor)
\]

于是使用传统艺能,代入
\[
S(n)=1-\sum_{d=2}^ng(d)*S(\lfloor \frac nd \rfloor)
\]

\[
S(n)=1-\sum_{d=2}^S(\lfloor \frac nd \rfloor)
\]

然后就可以和欧拉函数那个一样递归搞了

复杂度大约为 \(O(n^{\frac 23})\)

// This code wrote by chtholly_micromaker(MicroMaker)
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define reg register
#define int long long
using namespace std;
const int MaxN=3000050;
template <class t> inline void read(t &s)
{
    s=0;
    reg int f=1;
    reg char c=getchar();
    while(!isdigit(c))
    {
        if(c=='-')
            f=-1;
        c=getchar();
    }
    while(isdigit(c))
        s=(s<<3)+(s<<1)+(c^48),c=getchar();
    s*=f;
    return;
}
// bitset<MaxN> isp;
bool isp[MaxN];
int pr[MaxN],prn;
int phi[MaxN],mu[MaxN];
map<int,int> dp;
inline void Init(int n)
{
    phi[1]=mu[1]=1;
    for(int i=2;i<=n;++i)
    {
        // if(!isp.test(i))
        if(!isp[i])
        {
            pr[++prn]=i;
            phi[i]=i-1;
            mu[i]=-1;
        }
        for(int j=1;j<=prn&&i*pr[j]<=n;++j)
        {
            // isp.set(i*pr[j],1);
            reg int t=i*pr[j];
            isp[t]=true;
            if(i%pr[j])
            {
                phi[t]=phi[i]*(pr[j]-1);
                mu[t]=mu[i]*(-1);
            }
            else
            {
                phi[t]=phi[i]*pr[j];
                mu[t]=0;
                break;
            }
        }
    }
    for(int i=1;i<=n;++i)
        phi[i]+=phi[i-1],mu[i]+=mu[i-1];
    return;
}
inline int calcphi(int n)
{
    if(n<=3000000)
        return phi[n];
    if(dp.find(n)!=dp.end())
        return dp[n];
    reg int ans=0;
    for(reg int l=2,r;l<=n;l=r+1)
    {
        r=n/(n/l);
        ans+=(r-l+1)*calcphi(n/l);
    }
    ans=n*(n+1)/2-ans;
    dp[n]=ans;
    return ans;
}
inline int calcmu(int n)
{
    if(n<=3000000)
        return mu[n];
    if(dp.find(n)!=dp.end())
        return dp[n];
    reg int ans=0;
    for(reg int l=2,r;l<=n;l=r+1)
    {
        r=n/(n/l);
        ans+=(r-l+1)*calcmu(n/l);
    }
    dp[n]=1-ans;
    return 1-ans;
}
inline void work()
{
    int n;cin>>n;
    dp.clear();
    reg int ansphi=calcphi(n);
    dp.clear();
    reg int ansmu=calcmu(n);
    printf("%lld %lld\n",ansphi,ansmu);
    return;
}
signed main(void)
{
    Init(3000000);
    int t;cin>>t;
    while(t--)
        work();
    return 0;
}

如果 \(TLE\) 的话注意常数优化或者开启 \(Ofast\)

或者线筛筛到 \(3000000\) 也可以过

版权声明:本文为chinesepikaync原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/chinesepikaync/p/12284108.html