欧拉函数

前知导入

唯一分解定理

对于任何一个大于 \(1\) 的正整数都能分成有限个质数的乘积

即若 \(n\) 为大于 \(1\) 的整数,则有:\(n=\prod \limits_{i=1}^{m}p_i^{c_i}\)

其中,\(p_i\) 为质数且递增,\(p_i\leq n,c_i\geq 0\)


容斥原理

在此仅做简单引入

带入情景,班里有 \(10\) 个同学喜欢数学,\(5\) 个喜欢语文,\(8\) 个喜欢英语,求至少喜欢一门的学生个数

这个问题很好解决,讲喜欢这三科的学生的集合分别记作 \(A,B,C\),则至少喜欢一门的学生表示为 \(|A\cup B\cup C|\)

\(|A\cup B\cup C|=|A|+|B|+|C|-|A\cap B|-|A\cap C|-|B \cap C|+|A\cap B\cap C|\)

这就是简单的容斥原理


欧拉函数定义

写作 \(\varphi(n)\),表示小于等于 \(n\) 的正整数中与 \(n\) 互质的个数


\(\varphi(n)\)通式

\[\varphi(n)=\begin{cases} 1&n=1\\ n\times \prod\limits_{p\in\mathbb{p},p|n}(1-\dfrac{1}{p})&i\neq 1\\ \end{cases}\]


  • \(证明\)

    \(n>1\) 时,根据唯一分解定理,设 \(n=\prod\limits_{i=1}^{m}p_i^{c_i}\)其中 \(p_i,p_j\)\(n\) 的质因子

    \(1\sim n\) 中,\(p_i\) 的倍数有 \(\dfrac{n}{p_i}\) 个,\(p_j\) 的倍数有 \(\dfrac{n}{p_j}\)

    根据容斥原理,\(1\sim n\) 中不与 \(n\) 有共同因子 \(p_i\)\(p_j\) 的个数为 $$n-\dfrac{n}{p_i}-\dfrac{n}{p_j}+\dfrac{n}{p_i\times p_j}=n\times (1-\dfrac{1}{p_i}-\dfrac{1}{p_j}+\dfrac{1}{p_i\times p_j})=n\times (1-\dfrac{1}{p_i})\times (1-\dfrac{1}{p_j})$$

    以此类推,将 \(n\) 的全部质因子全部代入容斥原理,即可得到 \(\varphi(n)\)


  • \(代码实现\)

    1. 线性筛法求 \(1\sim n\) 的欧拉函数

      时间复杂度 \(O(n)\)

    void euler(int n)
    {
        phi[1]=1;
        for(int i=2;i<=n;i++)
        {
            if(!vis[i])
                len++,
                prime[len]=i,
                phi[i]=i-1;
            for(int j=1;j<=len&&i*prime[j]<=n;j++)
            {
                vis[i*prime[j]]=1;
                if(!(i%prime[j]))
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
    

    1. 求单个数的欧拉函数

      先对其分解质因数,然后带入公式

      单个数的复杂度为 \(O(\sqrt n)\)

    int phi(int x)
    {
        int ret=x;
        for(int i=2;i<=sqrt(n);i++)
            if(x%i==0)
            {
                ret=ret/i*(i-1);
                while(x%i==0) x/=i;
            }
        if(x>1) ret=ret/x*(x-1);
        return ret;
    }
    

性质

  1. \(n\) 为质数时,\(\varphi(n)=n-1\)
    • 显然

  1. 欧拉函数是积性函数

    • \(\gcd(a,b)=1\) 时,\(\varphi(a\times b)=\varphi(a)\times \varphi(b)\)

    • 由此不难推出,当 \(n\) 为奇数时,\(\varphi(2n)=\varphi(n)\)

    • 证明:

      根据唯一分解定理,不妨设 \(a=\prod\limits_{i=1}^{m}p_i^{c_i},b=\prod\limits_{i=1}^{m}q_i^{d_i}\)

      因为 \(\gcd(a,b)=1\),所以一定不存在一组 \(p_i=q_j\)

      那么 \(ab\) 可分解为 \(\prod\limits_{i=1}^{m}p_i^{c_i}\times \prod\limits_{i=1}^{m}q_i^{d_i}\),其中 \(p,q\) 一定不相等

      故此,依据性质 \(2\),则有 \(\varphi(ab)=ab\times \prod\limits_{i=1}^n(1-\dfrac{1}{p_i})\times \prod\limits_{i=1}^m(1-\dfrac{1}{q_i})\)

      又因为 \(\varphi(a)=a\times \prod\limits_{i=1}^n(1-\dfrac{1}{p_i}),\varphi(b)=b\times \prod\limits_{i=1}^m(1-\dfrac{1}{q_i})\)

      所以得到 \(\varphi(ab)=\varphi(a)\times \varphi(b)\)


  1. 欧拉反演

    \[n=\sum\limits_{d|n}\varphi(d)=\sum\limits_{d|n}\varphi(\dfrac{n}{d}) \]

    • 根据约数 \(d,\dfrac{n}{d}\) 的对称性

  1. \(n=p_k\)\(k\) 为质数,那么 \(\varphi(n)=p_k-p_{k-1}\)
    • 根据定义可得

  1. \(n\) 为正整数,则满足

    \[\sum_{i=1}^ni[\gcd(i,n)=1]=\begin{cases} 1&n=1\\ \dfrac{n\times\varphi(n)}{2}&i\neq 1\\ \end{cases}\]

    • 但在这里显然,当 \(n=1\) 时下面那个式子是不满足的,因此通式可以写成

    \[\sum_{i=1}^ni[\gcd(i,n)=1]=\lfloor{\dfrac{n\times\varphi(n)+1}{2}}\rfloor \]


相关知识扩展

欧拉定理

若正整数 \(a,b\) 满足 \(\gcd(a,b)=1\) ,则 $$a^{\varphi(m)}\equiv 1(\bmod m)$$

  • 在此只做描述,暂时未学费马小定理,不会证

扩展欧拉定理

\[a_b=\begin{cases} a^{b\bmod \varphi(p)}&\gcd(a,p)=1\\ a^b&\gcd(a,p)\neq 1,b<\varphi(p)~~~~~~~~~(\bmod p)\\ a^{b\bmod \varphi(p)+\varphi(p)}&\gcd(a,p)\neq 1,b\geq\varphi(p)\\ \end{cases}\]


例题

1. 仪仗队

  • \(题目链接\) \(仪仗队\)

  • \(问题处理\)

    如图:

    image

    这是一个正方形,不放将他看做一个三角形,再乘以 \(2\)

    以左下角点为原点 \((0,0)\) 建立坐标系

    设一点 \((x,y)\),当 \(x,y\) 互质时,即 \(\gcd(x,y)=1\) 时,他可以被看到

    反之,则一定有一点 \((\dfrac{x}{\gcd(x,y)},\dfrac{y}{gcd(x,y)})\) 将他挡住

    问题可转化为:\(i=1\sim (n-1)\) 中分别与 \(0\sim (i-1)\) 互质的个数

    也就是求 \(2\times \sum\limits_{i=1}^{n-1}\varphi(i)+1\)

    因为欧拉函数求的是 \(1\sim (i-1)\) 中与 \(i\) 互质的个数,但这里是从 \(0\) 开始的,所以纵坐标是 \(0\) 的这一条线上 \((1,0)\) 是可以看到的,后面都挡住了,所以要 \(+1\)\(\times 2\) 显然,因为我们是将他看做一个三角形去做的

    注意事项:\(1\sim (n-1)\) 而不是 \(1\sim n\),因为我们的第一列在坐标轴中视作 \(y=0\)


  • \(代码如下\)
    #include<bits/stdc++.h>
    #define int long long
    #define endl '\n'
    using namespace std;
    const int N=4e4+10;
    template<typename Tp> inline void read(Tp&x)
    {
        x=0;register bool z=1;
        register char c=getchar();
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
        for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
        x=(z?x:~x+1);
    }
    int n,len,ans,phi[N],prime[N],vis[N];
    void euler(int n)
    {
        phi[1]=1;
        for(int i=2;i<=n;i++)
        {
            if(!vis[i])
                len++,
                prime[len]=i,
                phi[i]=i-1;
            for(int j=1;j<=len&&i*prime[j]<=n;j++)
            {
                vis[i*prime[j]]=1;
                if(!(i%prime[j]))
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
    signed main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        read(n);
        euler(n);
        for(int i=1;i<n;i++) ans+=phi[i];
        cout<<(ans<<1)+1;
    }
    
    • 这里采用筛法求 \(1\sim (n-1)\) 的欧拉函数,复杂度 \(O(n)\),因为要求 \(1\sim (n-1)\) 的欧拉函数的和

2. \(Longge\) 的问题

  • \(题目链接\) \(Longge的问题\)

  • \(问题处理\)

    \(\sum\limits_{i=1}^{n}\gcd(i,n)\)

    \[\begin{align} &\sum\limits_{i=1}^{n}\gcd(i,n)\\ &=\sum\limits_{d|n}d\sum\limits_{i=1}^{n}[\gcd(i,n)=d]\\ &=\sum\limits_{d|n}d\sum\limits_{i=1}^{\dfrac{n}{d}}[\gcd(i,\dfrac{n}{d})=1]\\ &=\sum\limits_{d|n}d\times\varphi(\dfrac{n}{d})=\sum\limits_{d|n}\dfrac{n}{d}\times\varphi(d)(依据d与\dfrac{n}{d}的对称性)\\ \end{align}\]

    由此求即可


  • \(代码如下\)
    #include<bits/stdc++.h>
    #define int long long
    #define endl '\n'
    using namespace std;
    template<typename Tp> inline void read(Tp&x)
    {
        x=0;register bool z=1;
        register char c=getchar();
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
        for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
        x=(z?x:~x+1);
    }
    int n,len,ans;
    int phi(int x)
    {
        int ret=x;
        for(int i=2;i<=sqrt(n);i++)
            if(x%i==0)
            {
                ret=ret/i*(i-1);
                while(x%i==0) x/=i;
            }
        if(x>1) ret=ret/x*(x-1);
        return ret;
    }
    signed main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        read(n);
        for(int i=1;i<=sqrt(n);i++) 
            if(n%i==0) 
                if(i*i!=n) ans+=i*phi(n/i),ans+=(n/i)*phi(i);
                else ans+=i*phi(i);
        cout<<ans;
    }
    
    • 根据 \(d,\dfrac{n}{d}\) 的对称性,只需要 \(O(\sqrt n)\) 即可

3. \(Shadow\)公主的诱惑

  • \(题目链接\) \(沙拉公主的困惑\)

  • \(问题处理\)

    简化题意:求 \(\sum\limits_{i=1}^{n!}[\gcd(i,m!)=1]\)

    \[\begin{align} &\sum_{i=1}^{n!}[\gcd(i,m!)=1]\\ &=\dfrac{n!}{m!}\varphi(m!)\\ &=\dfrac{n!}{m!}\times m!\times \prod_{{p\in{p},p|m!}}(\dfrac{p-1}{p})\\ &=n!\times \prod_{{p\in\mathbb{p},p|m!}}(\dfrac{p-1}{p})\\ &=n!\times \prod_{p\in\mathbb{p}}^{m}(\dfrac{p-1}{p})\\ \end{align}\]

    由此求即可


  • \(程序实现\)

    多组测试数据,所以要先预处理(递推||筛法),不然显然会超时

    先设一个 \(N\) ,即数据范围,输入中给了总的 \(\bmod P\)

    根据上面推出的式子,需要先处理 质数阶乘乘法逆元\(\prod\limits_{i\in\mathbb{p}}^{N}(\dfrac{i-1}{i})\)

    • 质数是为了处理 \(\prod\limits_{i\in\mathbb{p}}^{N}(\dfrac{i-1}{i})\)
    • 阶乘显然是为了处理 \(n!\)的,别忘了 \(\bmod P\)
    • 至于乘法逆元,因为在 \(\bmod P\) 意义下,直接除以 \(i\) 是不行的,要用到 \(i^{-1}(\bmod P)\)
    • 之后就可以处理 \(\prod\limits_{i\in\mathbb{p}}^{N}(\dfrac{i-1}{i})\)

    这样对于每一组输入,直接 \(O(1)\) 输出即可


  • \(Hack数据\)

    \(n,m\) 中存在整除 \(R\) 时,式子出来就是 \(0\) 了,但显然不应该是 \(0\)

    对此,当循环到 \(R|i\) 时,将 \(i\) 中的 \(R\) 因子全部消掉,即

    int x=i;
    while(x%p==0) x/=p;
    

    在下面的代码中有体现

    同时,当 \(n>=R\)\(m<R\) 时,答案显然是 \(0\),需特判一下

    if(n>=p&&m<p) puts("0");
    

  • \(代码如下\)
    #include<bits/stdc++.h>
    #define int long long
    #define endl '\n'
    using namespace std;
    const int N=1e7+10;
    template<typename Tp> inline void read(Tp&x)
    {
        x=0;register bool z=1;
        register char c=getchar();
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
        for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
        x=(z?x:~x+1);
    }
    int t,p,n,m,jc[N],ans[N],inv[N];
    bool pri[N];
    void niyuan()
    {
        inv[1]=1;if(n>=p&&m<p) puts("0");
        for(int i=2;i<N;i++)
        {
            int x=i;
            while(x%p==0) x/=p;
            inv[i]=((p-p/x)*inv[p%x])%p;
        }
    }
    void prime()
    {
        for(int i=2;i<sqrt(N);i++)
            if(!pri[i])
                for(int j=2;i*j<N;j++)
                    pri[i*j]=1;
    }
    void prod()
    {
        jc[1]=1;
        for(int i=2;i<N;i++) 
        {
            int x=i;
            while(x%p==0) x/=p;
            jc[i]=(jc[i-1]*x)%p;
        }
    }
    void solve()
    {
        ans[1]=1;
        for(int i=2;i<N;i++)
            if(!pri[i]) 
            {
                int x=i,y=i-1;
                while(x%p==0) x/=p;
                while(y%p==0) y/=p;
                ans[i]=(ans[i-1]*y)%p,ans[i]=(ans[i]*inv[x])%p;
            }
            else ans[i]=ans[i-1];
    }
    signed main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        read(t),read(p);
        niyuan(),prime(),prod(),solve();
        while(t--)
        {
            read(n),read(m);
            if(n>=p&&m<p) puts("0");
            else cout<<(jc[n]*ans[m])%p<<endl;
        }
    }
    
    • 此处注意数组开的是 \([N]\),预处理的时候不能处理到 \(N\) 而应是 \(N-1\),不然会炸数组

4. \(GCD~SUM\)

  • \(题目链接\) \({GCD SUM}\)(P2398)

  • \(问题处理\)

    \[\begin{align} &\sum_{i=1}^{n}\sum_{j=1}^{n}\gcd(i,j)\\ &=\sum_{i=1}^n\sum_{j=1}^n\sum_{d|i,d|j}\varphi(d)\\ &=\sum_{d=1}^n\varphi(d)\sum_{i=1}^n[d|i]\sum_{j=1}^n[d|j]\\ &=\sum_{d=1}^n\varphi(d)\times\lfloor\dfrac{n}{d}\rfloor\times\lfloor\dfrac{n}{d}\rfloor\\ &=\sum_{d=1}^n\varphi(d)\times\lfloor\dfrac{n}{d}\rfloor^2\\ \end{align}\]


5. 能量采集

  • \(题目链接\) \(能量采集\)(P1447)

  • \(问题处理\)

    \(\sum\limits_{i=1}^n\sum\limits_{j=1}^m\gcd(i,j)\)

    看起来十分眼熟,和第 \(4\)\(GCD~SUM\) 是十分像的,借鉴那道题,则这道题的式子为:

    \[\begin{align} &设ans\\ &=\sum_{i=1}^{n}\sum_{j=1}^{m}\gcd(i,j)\\ &=\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}\varphi(d)\\ &=\sum_{d=1}^{\min(n,m)}\varphi(d)\sum_{i=1}^n[d|i]\sum_{j=1}^m[d|j]\\ &=\sum_{d=1}^{\min(n,m)}\varphi(d)\times\lfloor\dfrac{n}{d}\rfloor\times\lfloor\dfrac{m}{d}\rfloor\\ \end{align}\]

    但是仔细阅读题面,他并不是上面的式子,拿 \((4,8)\) 打比方,他前面有 \((1,2)、(2,4)、(3,6)\) 三个点,所以该点的能量损失为 \(2\times 3+1=7\),而 \(\gcd(4,8)=4\) 所以要求的实际上应该是

    \[\sum\limits_{i=1}^n\sum\limits_{j=1}^m2\times(\gcd(i,j)-1)+1=\sum\limits_{i=1}^n\sum\limits_{j=1}^m2\times\gcd(i,j)-1 \]

    那么简单转化一下即可,即 \(ans\times 2-n\times m\)


6. 公约数的和

  • \(题目链接\) \(公约数的和\)(P1390)

  • \(问题处理\)

    \(\sum\limits_{i=1}^n\sum\limits_{j=i+1}^n\gcd(i,j)\)

    可以借鉴我们上面这道题

    \[\sum_{i=1}^{n}\sum_{j=1}^{n}\gcd(i,j)=\sum\limits_{i=1}^n\sum\limits_{j=i+1}^n\gcd(i,j)+\sum\limits_{i=1}^n\sum\limits_{j=1}^{i-1}\gcd(i,j)+\sum_{i=1}^n\gcd(i,i) \]

    其中,\(\sum\limits_{i=1}^n\sum\limits_{j=1}^{i-1}\gcd(i,j)\)\(\sum\limits_{i=1}^n\sum\limits_{j=i+1}^n\gcd(i,j)\) 显然是相等的

    \(\sum\limits_{i=1}^n\gcd(i,i)=\sum\limits_{i=1}^ni=\dfrac{n\times(n+1)}{2}\)

    所以 \(\sum\limits_{i=1}^n\sum\limits_{j=i+1}^n\gcd(i,j)=\dfrac{\sum\limits_{i=1}^n\sum\limits_{j=1}^n\gcd(i,j)-\dfrac{n\times(n+1)}{2}}{2}\)

    再套用上面那道题的式子即可


7. \(\text{Same~GCDs}\)

  • \(题目链接\) \(\text{Same~GCDs}\)(CF1295D)

  • \(问题处理\)

    \(\sum\limits_{x=0}^{m-1}[\gcd(a,m)=\gcd(a+x,m)]\)

    如果将 \(a,m\) 分别分解质因数的话,\(\gcd(a,m)\) 即他们公共的那一部分,不难发现,\(x\) 需满足 \(\gcd(a,m)|x\) 且不能包含 \(m\) 除去 \(\gcd(a,m)\) 的那一部分质因数

    \(\gcd(a,m)=\gcd(x,m)\)

    \[\begin{align} &\sum_{x=0}^{m-1}[\gcd(a,m)=\gcd(a+x,m)]\\ &=\sum_{x=0}^{m-1}[\gcd(a,m)=\gcd(x,m)]\\ &=\sum_{x=0}^{m-1}[\gcd(\dfrac{x}{\gcd(a,m)},\dfrac{m}{\gcd(a,m)})=1]\\ &=\varphi(\dfrac{m}{\gcd(a,m)})\\ \end{align}\]

    由此求即可


8. 疯狂\(LCM\)

  • \(题目链接\) \({疯狂LCM}\)(P1891)

  • \(问题处理\)

    \(\text{lcm}\) 是最小公倍数的意思,\(\text{lcm}(a,b)=\dfrac{a\times b}{\gcd(a,b)}\)

    \[\begin{align} &\sum_{i=1}^n\text{lcm}(i,n)\\ &=\sum_{i=1}^n\dfrac{i\times n}{\gcd(i,n)}\\ &=n\times\sum_{i=1}^n\dfrac{i}{\gcd(i,n)}\\ &=n\times\sum_{d|n}\sum_{i=1}^n\dfrac{i}{d}[\gcd(i,n)=d]\\ &\small{括号内同时除以 d }\\ &=n\times\sum_{d|n}\sum_{i=1}^{n}\dfrac{i}{d}[\gcd(\dfrac{i}{d},\dfrac{n}{d})=1]\\ &用 i 替换\dfrac{i}{d}\\ &=n\times\sum_{d|n}\sum_{i=1}^{\dfrac{n}{d}}i[\gcd(i,\dfrac{n}{d})=1]\\ &根据性质5\\ &=n\times\sum_{d|n}\dfrac{1+d\times\varphi(d)}{2}\\ \end{align}\]

    由此求即可


  • \(程序实现\)

    多组测试数据,需要预处理

    欧拉函数筛法预处理,之后在线性预处理 \(\sum\limits_{d|n}\dfrac{1+d\times\varphi(d)}{2}\),之后 \(O(1)\) 输出即可

    预处理代码如下:

    void euler(int n)
    {
        phi[1]=1;
        for(int i=2;i<=n;i++)
        {
            if(!vis[i])
                len++,
                prime[len]=i,
                phi[i]=i-1;
            for(int j=1;j<=len&&i*prime[j]<=n;j++)
            {
                vis[i*prime[j]]=1;
                if(!(i%prime[j]))
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
    void solve(int n)
    {
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j+=i)
                ans[j]+=(phi[i]*i+1)>>1;
    }
    

    至于 \(solve\) 的那一部分预处理之前没有用过,新学一下

    根据式子 \(\sum\limits_{d|n}\dfrac{1+d\times\varphi(d)}{2}\),带入我们的代码,定满足 \(i|j\),因为是 \(j+=i\)


  • \(代码如下\)
    #include<bits/stdc++.h>
    #define int long long
    #define endl '\n'
    using namespace std;
    const int N=1e6+1;
    template<typename Tp> inline void read(Tp&x)
    {
        x=0;register bool z=1;
        register char c=getchar();
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
        for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
        x=(z?x:~x+1);
    }
    int t,n,len,ans[N],prime[N],phi[N];
    bool vis[N];
    void euler(int n)
    {
        phi[1]=1;
        for(int i=2;i<=n;i++)
        {
            if(!vis[i])
                len++,
                prime[len]=i,
                phi[i]=i-1;
            for(int j=1;j<=len&&i*prime[j]<=n;j++)
            {
                vis[i*prime[j]]=1;
                if(!(i%prime[j]))
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
    void solve(int n)
    {
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j+=i)
                ans[j]+=(phi[i]*i+1)>>1;
    }
    signed main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        euler(N);
        solve(N);
        read(t);
        while(t--)
            read(n),
            cout<<ans[n]*n<<endl;
    }
    

9. \(GCD\)

  • \(题目链接\) \(GCD\)(P2568)

  • \(问题处理\)

    \(\sum\limits_{i=1}^n\sum\limits_{j=1}^n[\gcd(i,j)\in\mathbb{P}]\)

    \[\begin{align} & \sum\limits_{i=1}^n\sum\limits_{j=1}^n[\gcd(i,j)\in\mathbb{P}]\\ &=\sum_{i=1}^n\sum_{j=1}^n\sum_{d\in\mathbb{P}}^n[\gcd(i,j)=d]\\ &=\sum_{i=1}^n\sum_{j=1}^n\sum_{d\in\mathbb{P}}^n[\gcd(\dfrac{i}{d},\dfrac{j}{d})=1]\\ &=\sum_{d\in\mathbb{P}}^n\sum_{i=1}^{\dfrac{n}{d}}\sum_{j=1}^{\dfrac{n}{d}}[\gcd(i,j)=1]\\ &=\sum_{d\in\mathbb{P}}^n(-1+2\times\sum_{i=1}^{\dfrac{n}{d}}\varphi(i))\\ \end{align}\]

    至于最后一步怎么出来的

    我们知道 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^{i}[\gcd(i,j)=1]=\sum\limits_{i=1}^n\varphi(i)=\sum\limits_{i=1}^n\sum\limits_{j=i}^{n}[\gcd(i,j)=1]\)

    同时 \(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^n=\sum\limits_{i=1}^n\sum\limits_{j=1}^{i}+\sum\limits_{i=1}^n\sum\limits_{j=i}^{n}\)

    但有一个例外,当 \(n=1\) 时,\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^n=\sum\limits_{i=1}^n\sum\limits_{j=1}^{i}=\sum\limits_{i=1}^n\sum\limits_{j=i}^{n}\)

    于是就有了 \(\sum\limits_{d\in\mathbb{P}}^n\sum\limits_{i=1}^{\dfrac{n}{d}}\sum\limits_{j=1}^{\dfrac{n}{d}}[\gcd(i,j)=1]=\sum\limits_{d\in\mathbb{P}}^n(-1+2\times\sum\limits_{i=1}^{\dfrac{n}{d}}\varphi(i))\)

    减去 \(1\) 即考虑 \(\dfrac{n}{d}=1\) 的那个情况


  • 注意事项

    预处理的时候,数组开的是 \(N\),循环到 \(N\) 就炸了!,所以预处理到 \(N-1!!!\)

    不知道第几次因为这个WA了


posted @ 2024-01-09 20:02  卡布叻_周深  阅读(26)  评论(2编辑  收藏  举报