Prefix Sum

这篇博客探讨了数论中的一些常见问题,如莫比乌斯函数之和、欧拉函数之和、最大公约数与最小公倍数的求和等。通过介绍杜教筛、分块方法等技巧,阐述了如何利用数学方法,如反演和积性函数,解决这些数论问题。同时,文章提供了51Nod和洛谷等平台的相关题目作为实践案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上套路

  • 反演
    F ( n ) = ∑ d ∣ n f ( d ) = > f ( n ) = ∑ d ∣ n μ ( d ) F ( n d ) F(n)=\sum\limits_{d|n}f(d)=>f(n)=\sum\limits_{d|n}\mu(d)F(\frac{n}d) F(n)=dnf(d)=>f(n)=dnμ(d)F(dn)
    F ( n ) = ∑ n ∣ d f ( d ) = > f ( n ) = ∑ n ∣ d μ ( d n ) F ( d ) F(n)=\sum\limits_{n|d}f(d)=>f(n)=\sum\limits_{n|d}\mu(\frac{d}n)F(d) F(n)=ndf(d)=>f(n)=ndμ(nd)F(d)

  • μ 与 ϕ \mu与\phi μϕ
    ∑ d ∣ n μ ( d ) = [ n = = 1 ] \sum\limits_{d|n}\mu(d)=[n==1] dnμ(d)=[n==1]
    ∑ d ∣ n ϕ ( d ) = n \sum\limits_{d|n}\phi(d)=n dnϕ(d)=n
    ϕ ( n ) n = ∑ d ∣ n μ ( d ) d \frac{\phi(n)}{n}=\sum\limits_{d|n}\frac{\mu(d)}{d} nϕ(n)=dndμ(d)
    ϕ ( n ) = ∑ d ∣ n μ ( d ) n d \phi(n)=\sum\limits_{d|n}\mu(d)\frac{n}{d} ϕ(n)=dnμ(d)dn

  • σ 约 数 和 \sigma约数和 σ
    σ ( n ) = ∑ d ∣ n d \sigma(n)=\sum\limits_{d|n}d σ(n)=dnd
    ∑ i = 1 n σ ( i ) = ∑ i = 1 n i ∗ ⌊ n i ⌋ \sum\limits_{i=1}^{n}\sigma(i)=\sum\limits_{i=1}^ni*\left \lfloor \frac{n}{i} \right \rfloor i=1nσ(i)=i=1niin
    σ k ( i ∗ j ) = ∑ x ∣ i n ∑ y ∣ j n [ g c d ( x , y ) = = 1 ] x k ∗ j k / y k \sigma_k(i*j)=\sum\limits_{x|i}^n\sum\limits_{y|j}^n[gcd(x,y)==1]x^k*j^k/y^k σk(ij)=xinyjn[gcd(x,y)==1]xkjk/yk
    k 等 于 0 就 是 约 数 个 数 和 k等于0就是约数个数和 k0

  • 杜 教 筛 杜教筛
    g 1 S ( n ) = ∑ i = 1 n h ( i ) − ∑ i = 2 n g ( i ) S ( ⌊ n i ⌋ ) g_1S(n)=\sum\limits_{i=1}^nh(i)-\sum\limits_{i=2}^ng(i)S(\left \lfloor \frac{n}{i} \right \rfloor) g1S(n)=i=1nh(i)i=2ng(i)S(in)
    h = f ∗ g h=f*g h=fg
    ∑ i = 1 n i 2 = n ( n + 1 ) ( 2 n + 1 ) 6 \sum\limits_{i=1}^n{i^2}=\frac{n(n+1)(2n+1)}{6} i=1ni2=6n(n+1)(2n+1)
    ∑ i = 1 n i 3 = ( n ( n + 1 ) 2 ) 2 \sum\limits_{i=1}^n{i^3}=(\frac{n(n+1)}{2})^2 i=1ni3=(2n(n+1))2

  • g c d ( a n − b n , a m − b m ) = a g c d ( n , m ) − b g c d ( n , m ) gcd(a^n-b^n,a^m-b^m)=a^{gcd(n,m)}-b^{gcd(n,m)} gcd(anbn,ambm)=agcd(n,m)bgcd(n,m)
    g c d ( a n − 1 , a m − 1 ) = a g c d ( n , m ) − 1 gcd(a^n-1,a^m-1)=a^{gcd(n,m)}-1 gcd(an1,am1)=agcd(n,m)1

  • g c d ( F i b m , F i b n ) = F i b g c d ( n , m ) gcd(Fib_m,Fib_n)=Fib_{gcd(n,m)} gcd(Fibm,Fibn)=Fibgcd(n,m)

  • ∑ i = 1 n 1 i ∑ j = 1 i l c m ( i , j ) = 1 2 ( ∑ d = 1 n ∑ i = 1 n d i ϕ ( i ) + n ) \sum\limits_{i=1}^n\frac{1}{i}\sum\limits_{j=1}^{i}lcm(i,j)=\frac{1}{2}(\sum\limits_{d=1}^n\sum\limits_{i=1}^{\frac{n}{d}}i\phi(i)+n) i=1ni1j=1ilcm(i,j)=21(d=1ni=1dniϕ(i)+n)

51Nod 1244 - 莫比乌斯函数之和

51Nod 1239 - 欧拉函数之和

51Nod 1237 - 最大公约数之和 V3

51Nod 1238 - 最小公倍数之和 V3

51Nod 1227 - 平均最小公倍数

51Nod 1220 - 约数之和

HDU 6706 - huntian oy

洛谷 P2257 - YY的GCD

51Nod 1244 - 莫比乌斯函数之和

回目录

杜教筛, h = μ ∗ g h=\mu*g h=μg卷上恒等函数 I ( n ) , 即 g = 1 I(n),即g=1 I(n),g=1
∑ i = 1 n h ( i ) = 1 \sum\limits_{i=1}^nh(i)=1 i=1nh(i)=1
S ( n ) = 1 − ∑ i = 2 n S ( ⌊ n i ⌋ ) S(n)=1-\sum\limits_{i=2}^nS(\left \lfloor \frac{n}{i} \right \rfloor) S(n)=1i=2nS(in)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
int su[N],mu[N],num,vis[N];
unordered_map<LL,LL> mp;
void init()
{
    mu[1]=1;
    for(int i=2;i<N;++i){
        if(!vis[i])su[++num]=i,mu[i]=-1;
        for(int j=1;j<=num&&i*su[j]<N;++j){
            vis[i*su[j]]=1;
            if(i%su[j]==0)break;
            mu[i*su[j]]=-mu[i];
        }
    }
    for(int i=1;i<N;++i)mu[i]+=mu[i-1];
}
LL djs(LL n)
{
    if(n<N)return mu[n];
    if(mp[n])return mp[n];
    LL ans=1;
    for(LL L=2,R;L<=n;L=R+1){
        R=n/(n/L);
        ans-=(R-L+1)*djs(n/L);
    }
    return mp[n]=ans;
}
int main()
{
    init();
    LL L,R;
    scanf("%lld%lld",&L,&R);
    printf("%lld\n",djs(R)-djs(L-1));
    return 0;
}

51Nod 1239 - 欧拉函数之和

回目录

杜教筛, h = ϕ ∗ g h=\phi*g h=ϕg卷上恒等函数 I ( n ) , 即 g = 1 , 则 h ( n ) = n I(n),即g=1,则h(n)=n I(n),g=1,h(n)=n
∑ i = 1 n h ( i ) = ( n ∗ n + 1 ) / 2 \sum\limits_{i=1}^nh(i)=(n*n+1)/2 i=1nh(i)=(nn+1)/2
S ( n ) = ( n ∗ n + 1 ) / 2 − ∑ i = 2 n S ( ⌊ n i ⌋ ) S(n)=(n*n+1)/2-\sum\limits_{i=2}^nS(\left \lfloor \frac{n}{i} \right \rfloor) S(n)=(nn+1)/2i=2nS(in)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
int su[N],phi[N],num,vis[N];
unordered_map<LL,LL> mp;
const LL mod=1e9+7;
const LL inv2=500000004;
void init()
{
    phi[1]=1;
    for(int i=2;i<N;++i){
        if(!vis[i])su[++num]=i,phi[i]=i-1;
        for(int j=1;j<=num&&i*su[j]<N;++j){
            vis[i*su[j]]=1;
            if(i%su[j]==0){
                phi[i*su[j]]=phi[i]*su[j];
                break;
            }
            phi[i*su[j]]=phi[i]*phi[su[j]];
        }
    }
    for(int i=1;i<N;++i)phi[i]=(phi[i]+phi[i-1])%mod;
}
LL sum(LL n)
{
    n%=mod;
    return n*(n+1)%mod*inv2%mod;
}
LL djs(LL n)
{
    if(n<N)return phi[n];
    if(mp[n])return mp[n];
    LL ans=sum(n);
    for(LL L=2,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans-(R-L+1)%mod*djs(n/L)%mod+mod)%mod;
    }
    return mp[n]=ans;
}
int main()
{
    init();
    LL n;
    scanf("%lld",&n);
    printf("%lld\n",djs(n));
    return 0;
}

51Nod 1237 - 最大公约数之和 V3

回目录

∑ i = 1 n ∑ j = 1 n g c d ( i , j ) = ∑ i = 1 n ∑ j = 1 n ∑ d ∣ g c d ( i , j ) ϕ ( d ) = ∑ d = 1 n ϕ ( d ) ∑ i = 1 n ∑ j = 1 n [ d ∣ g c d ( i , j ) ] = ∑ d = 1 n ϕ ( d ) ∑ i = 1 n d ∑ j = 1 n d 1 = ∑ d = 1 n ϕ ( d ) ⌊ n i ⌋ 2 \begin{aligned}\sum\limits_{i=1}^n\sum\limits_{j=1}^ngcd(i,j) &=\sum\limits_{i=1}^n\sum\limits_{j=1}^n\sum\limits\limits_{d|gcd(i,j)}\phi(d)\\ &=\sum\limits_{d=1}^n\phi(d)\sum\limits_{i=1}^n\sum\limits_{j=1}^n[d|gcd(i,j)]\\ &=\sum\limits_{d=1}^n\phi(d)\sum\limits_{i=1}^{\frac{n}d}\sum\limits_{j=1}^{\frac{n}d}1\\ &=\sum\limits_{d=1}^n\phi(d){\left \lfloor \frac{n}{i} \right \rfloor}^2\\ \end{aligned} i=1nj=1ngcd(i,j)=i=1nj=1ndgcd(i,j)ϕ(d)=d=1nϕ(d)i=1nj=1n[dgcd(i,j)]=d=1nϕ(d)i=1dnj=1dn1=d=1nϕ(d)in2

杜教筛加分块即可

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
int su[N],phi[N],num,vis[N];
unordered_map<LL,LL> mp;
const LL mod=1e9+7;
const LL inv2=500000004;
void init()
{
    phi[1]=1;
    for(int i=2;i<N;++i){
        if(!vis[i])su[++num]=i,phi[i]=i-1;
        for(int j=1;j<=num&&i*su[j]<N;++j){
            vis[i*su[j]]=1;
            if(i%su[j]==0){
                phi[i*su[j]]=phi[i]*su[j];
                break;
            }
            phi[i*su[j]]=phi[i]*phi[su[j]];
        }
    }
    for(int i=1;i<N;++i)phi[i]=(phi[i]+phi[i-1])%mod;
}
LL sum(LL n)
{
    n%=mod;
    return n*(n+1)%mod*inv2%mod;
}
LL djs(LL n)
{
    if(n<N)return phi[n];
    if(mp[n])return mp[n];
    LL ans=sum(n);
    for(LL L=2,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans-(R-L+1)%mod*djs(n/L)%mod+mod)%mod;
    }
    return mp[n]=ans;
}
LL outside(LL n)
{
    LL ans=0;
    for(LL L=1,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans+(djs(R)-djs(L-1)+mod)%mod*((n/L)%mod)*((n/L)%mod)+mod)%mod;
    }
    return ans;
}
int main()
{
    init();
    LL n;
    scanf("%lld",&n);
    printf("%lld\n",outside(n));
    return 0;
}

51Nod 1238 - 最小公倍数之和 V3

回目录

∑ i = 1 n ∑ j = 1 n l c m ( i , j ) = ∑ d = 1 n ∑ i = 1 n ∑ j = 1 n i j d [ d = = g c d ( i , j ) ] = ∑ d = 1 n d ∑ i = 1 n / d ∑ j = 1 n / d i j [ 1 = = g c d ( i , j ) ] = ∑ d = 1 n d ∑ i = 1 n d i 2 ϕ ( i ) \begin{aligned}\sum\limits_{i=1}^n\sum\limits_{j=1}^nlcm(i,j) &=\sum\limits_{d=1}^n\sum\limits_{i=1}^n\sum\limits_{j=1}^n\frac{ij}{d}[d==gcd(i,j)] \\ &=\sum\limits_{d=1}^nd\sum\limits_{i=1}^{n/d}\sum\limits_{j=1}^{n/d}ij[1==gcd(i,j)]\\ &=\sum\limits_{d=1}^nd\sum\limits_{i=1}^{\frac{n}d}i^2\phi(i)\\ \\ \end{aligned} i=1nj=1nlcm(i,j)=d=1ni=1nj=1ndij[d==gcd(i,j)]=d=1ndi=1n/dj=1n/dij[1==gcd(i,j)]=d=1ndi=1dni2ϕ(i)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int su[N],num,vis[N];
LL phi[N];
unordered_map<LL,LL> mp;
void init()
{
    phi[1]=1;
    for(int i=2;i<N;++i){
        if(!vis[i])su[++num]=i,phi[i]=i-1;
        for(int j=1;j<=num&&i*su[j]<N;++j){
            vis[i*su[j]]=1;
            if(i%su[j]==0){
                phi[i*su[j]]=phi[i]*su[j];
                break;
            }
            phi[i*su[j]]=phi[i]*phi[su[j]];
        }
    }
    for(int i=1;i<N;++i)phi[i]=(phi[i]*i%mod*i%mod+phi[i-1])%mod;
}
LL sum(LL n)
{
    n%=mod;
    return n*(n+1)%mod*inv2%mod;
}
LL get(LL n)
{
    n%=mod;
    return n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
}
LL djs(LL n)
{
    if(n<(LL)N)return phi[n];
    if(mp[n])return mp[n];
    LL ans=sum(n);
    ans=ans*ans%mod;
    for(LL L=2,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans-(get(R)-get(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
    }
    return mp[n]=ans;
}
LL outside(LL n)
{
    LL ans=0;
    for(LL L=1,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans+(sum(R)-sum(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
    }
    return ans;
}
int main()
{
    init();
    LL n;
    scanf("%lld",&n);
    printf("%lld\n",outside(n));
    return 0;
}

51Nod 1227 - 平均最小公倍数

回目录

∑ i = 1 n 1 i ∑ j = 1 i l c m ( i , j ) = ∑ d = 1 n ∑ i = 1 n ∑ j = 1 i j d [ d = = g c d ( i , j ) ] = ∑ d = 1 n ∑ i = 1 n ∑ j = 1 i [ 1 = = g c d ( i , j ) ] = ∑ d = 1 n ∑ i = 1 n d i ϕ ( i ) + [ i = = 1 ] 2 = ∑ d = 1 n ∑ i = 1 n i ϕ ( i ) + n 2 \begin{aligned}\sum\limits_{i=1}^n\frac{1}{i}\sum\limits_{j=1}^ilcm(i,j) &=\sum\limits_{d=1}^n\sum\limits_{i=1}^n\sum\limits_{j=1}^i\frac{j}{d}[d==gcd(i,j)] \\ &=\sum\limits_{d=1}^n\sum\limits_{i=1}^n\sum\limits_{j=1}^i[1==gcd(i,j)]\\ &=\sum\limits_{d=1}^n\sum\limits_{i=1}^{\frac{n}d}\frac{i\phi(i)+[i==1]}{2}\\ &=\frac{\sum\limits_{d=1}^n\sum\limits_{i=1}^ni\phi(i)+n}{2}\\ \\ \end{aligned} i=1ni1j=1ilcm(i,j)=d=1ni=1nj=1idj[d==gcd(i,j)]=d=1ni=1nj=1i[1==gcd(i,j)]=d=1ni=1dn2iϕ(i)+[i==1]=2d=1ni=1niϕ(i)+n

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int su[N],num,vis[N];
LL phi[N];
unordered_map<LL,LL> mp;
void init()
{
    phi[1]=1;
    for(int i=2;i<N;++i){
        if(!vis[i])su[++num]=i,phi[i]=i-1;
        for(int j=1;j<=num&&i*su[j]<N;++j){
            vis[i*su[j]]=1;
            if(i%su[j]==0){
                phi[i*su[j]]=phi[i]*su[j];
                break;
            }
            phi[i*su[j]]=phi[i]*phi[su[j]];
        }
    }
    for(int i=1;i<N;++i)phi[i]=(phi[i]*i%mod+phi[i-1])%mod;
}
LL sum(LL n)
{
    n%=mod;
    return n*(n+1)%mod*inv2%mod;
}
LL get(LL n)
{
    n%=mod;
    return n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
}
LL djs(LL n)
{
    if(n<(LL)N)return phi[n];
    if(mp[n])return mp[n];
    LL ans=get(n);
    for(LL L=2,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans-(sum(R)-sum(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
    }
    return mp[n]=ans;
}
LL outside(LL n)
{
    LL ans=0;
    for(LL L=1,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans+(R-L+1+mod)%mod*djs(n/L)%mod+mod)%mod;
    }
    return (ans+n)%mod*inv2%mod;
}
int main()
{
    init();
    LL n,m;
    scanf("%lld%lld",&n,&m);
    printf("%lld\n",(outside(m)-outside(n-1)+mod)%mod);
    return 0;
}

51Nod 1220 - 约数之和

回目录

∑ i = 1 n ∑ j = 1 i d ( i , j ) = ∑ i = 1 n ∑ j = 1 n ∑ x ∣ i ∑ y ∣ j x j y [ 1 = = g c d ( x , y ) ] = ∑ d = 1 n μ ( d ) ∑ i = 1 n ∑ j = 1 n ∑ x ∣ i ∑ y ∣ j x j y [ d ∣ g c d ( x , y ) ] = ∑ d = 1 n μ ( d ) d ∑ i = 1 n d ∑ j = 1 n d ∑ x ∣ i ∑ y ∣ j x j y = ∑ d = 1 n μ ( d ) d ∑ i = 1 n d ∑ x ∣ i x ∑ j = 1 n d ∑ y ∣ j j y = ∑ d = 1 n d μ ( d ) ( ∑ i = 1 n d σ ( i ) ) 2 = ∑ d = 1 n d μ ( d ) ( ∑ i = 1 n d i ⌊ n d i ⌋ ) 2 \begin{aligned}\sum\limits_{i=1}^n\sum\limits_{j=1}^id(i,j) &=\sum\limits_{i=1}^n\sum\limits_{j=1}^n\sum\limits_{x|i}\sum\limits_{y|j}\frac{xj}{y}[1==gcd(x,y)] \\ &=\sum\limits_{d=1}^n\mu(d)\sum\limits_{i=1}^n\sum\limits_{j=1}^n\sum\limits_{x|i}\sum\limits_{y|j}\frac{xj}{y}[d|gcd(x,y)] \\ &=\sum\limits_{d=1}^n\mu(d)d\sum\limits_{i=1}^{\frac{n}d}\sum\limits_{j=1}^{\frac{n}d}\sum\limits_{x|i}\sum\limits_{y|j}\frac{xj}{y}\\ &=\sum\limits_{d=1}^n\mu(d)d\sum\limits_{i=1}^{\frac{n}d}\sum\limits_{x|i}x\sum\limits_{j=1}^{\frac{n}d}\sum\limits_{y|j}\frac{j}{y}\\ &=\sum\limits_{d=1}^nd\mu(d)(\sum\limits_{i=1}^{\frac{n}d}\sigma(i))^2\\ &=\sum\limits_{d=1}^nd\mu(d)(\sum\limits_{i=1}^{\frac{n}d}i{\left \lfloor \frac{n}{di} \right \rfloor})^2\\ \\ \end{aligned} i=1nj=1id(i,j)=i=1nj=1nxiyjyxj[1==gcd(x,y)]=d=1nμ(d)i=1nj=1nxiyjyxj[dgcd(x,y)]=d=1nμ(d)di=1dnj=1dnxiyjyxj=d=1nμ(d)di=1dnxixj=1dnyjyj=d=1ndμ(d)(i=1dnσ(i))2=d=1ndμ(d)(i=1dnidin)2

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int su[N],num,vis[N],mu[N];
unordered_map<int,LL> mp;
void init()
{
    mu[1]=1;
    for(int i=2;i<N;++i){
        if(!vis[i])su[++num]=i,mu[i]=-1;
        for(int j=1;j<=num&&i*su[j]<N;++j){
            vis[i*su[j]]=1;
            if(i%su[j]==0)break;
            mu[i*su[j]]=-mu[i];
        }
    }
    for(int i=1;i<N;++i)mu[i]=(mu[i]*i+mu[i-1]+mod)%mod;
}
LL sum(int n)
{
    return (LL)n*(n+1)%mod*inv2%mod;
}
LL djs(int n)
{
    if(n<N)return mu[n];
    if(mp[n])return mp[n];
    LL ans=1;
    for(int L=2,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans-(sum(R)-sum(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
    }
    return mp[n]=ans;
}
LL inside(int n)
{
    LL ans=0;
    for(int L=1,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans+(sum(R)-sum(L-1)+mod)%mod*(n/L)%mod+mod)%mod;
    }
    return ans*ans%mod;
}
LL outside(int n)
{
    LL ans=0;
    for(int L=1,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans+(djs(R)-djs(L-1)+mod)%mod*inside(n/L)%mod+mod)%mod;
    }
    return ans;
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    printf("%lld\n",outside(n));
    return 0;
}

HDU 6706 - huntian oy

回目录

∑ i = 1 n ∑ j = 1 i g c d ( i a − j a , i b − j b ) [ g c d ( i , j ) = = 1 ] = ∑ i = 1 n ∑ j = 1 i ( i − j ) [ g c d ( i , j ) = = 1 ] = ∑ i = 1 n ∑ j = 1 i i [ g c d ( i , j ) = = 1 ] − ∑ i = 1 n ∑ j = 1 i j [ g c d ( i , j ) = = 1 ] = ∑ i = 1 n i ϕ ( i ) − ∑ i = 1 n i ϕ ( i ) + [ n = = 1 ] 2 = 1 + ∑ i = 2 n i ϕ ( i ) − ( 1 + ∑ i = 2 n i ϕ ( i ) 2 ) = ∑ i = 2 n i ϕ ( i ) 2 = ∑ i = 1 n i ϕ ( i ) − 1 2 \begin{aligned}\sum\limits_{i=1}^n\sum\limits_{j=1}^igcd(i^a-j^a,i^b-j^b)[gcd(i,j)==1] &=\sum\limits_{i=1}^n\sum\limits_{j=1}^i(i-j)[gcd(i,j)==1] \\ &=\sum\limits_{i=1}^n\sum\limits_{j=1}^ii[gcd(i,j)==1]- \sum\limits_{i=1}^n\sum\limits_{j=1}^ij[gcd(i,j)==1]\\ &=\sum\limits_{i=1}^ni\phi(i)-\frac{\sum\limits_{i=1}^ni\phi(i)+[n==1]}{2}\\ &=1+\sum\limits_{i=2}^ni\phi(i)-(1+\frac{\sum\limits_{i=2}^ni\phi(i)}{2})\\ &=\frac{\sum\limits_{i=2}^ni\phi(i)}{2}\\ &=\frac{\sum\limits_{i=1}^ni\phi(i)-1}{2}\\ \\ \end{aligned} i=1nj=1igcd(iaja,ibjb)[gcd(i,j)==1]=i=1nj=1i(ij)[gcd(i,j)==1]=i=1nj=1ii[gcd(i,j)==1]i=1nj=1ij[gcd(i,j)==1]=i=1niϕ(i)2i=1niϕ(i)+[n==1]=1+i=2niϕ(i)(1+2i=2niϕ(i))=2i=2niϕ(i)=2i=1niϕ(i)1

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int su[N],num,vis[N];
LL phi[N];
unordered_map<int,LL> mp;
void init()
{
    phi[1]=1;
    for(int i=2;i<N;++i){
        if(!vis[i])su[++num]=i,phi[i]=i-1;
        for(int j=1;j<=num&&i*su[j]<N;++j){
            vis[i*su[j]]=1;
            if(i%su[j]==0){
                phi[i*su[j]]=phi[i]*su[j];
                break;
            }
            phi[i*su[j]]=phi[i]*phi[su[j]];
        }
    }
    for(int i=1;i<N;++i)phi[i]=(phi[i]*i%mod+phi[i-1]+mod)%mod;
}
LL sum(int n)
{
    return (LL)n*(n+1)%mod*inv2%mod;
}
LL djs(int n)
{
    if(n<N)return phi[n];
    if(mp[n])return mp[n];
    LL ans=(LL)n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
    for(int L=2,R;L<=n;L=R+1){
        R=n/(n/L);
        ans=(ans-(sum(R)-sum(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
    }
    return mp[n]=ans;
}
int main()
{
    init();
    int n,T,a,b;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&a,&b);
        printf("%lld\n",(djs(n)-1+mod)%mod*inv2%mod);
    }
    return 0;
}

洛谷 P2257 - YY的GCD

回目录

∑ p ∈ p r i m e ∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = = p ] = ∑ p ∈ p r i m e ∑ i = 1 n p ∑ j = 1 n p [ g c d ( i , j ) = = 1 ] = ∑ p ∈ p r i m e ∑ d = 1 m i n ( n p , m p ) μ ( d ) ∑ i = 1 n p ∑ j = 1 n p [ d ∣ g c d ( i , j ) ] = ∑ p ∈ p r i m e ∑ d = 1 m i n ( n p , m p ) μ ( d ) ∑ i = 1 n p d ∑ j = 1 n p d 1 = ∑ p ∈ p r i m e ∑ d = 1 m i n ( n p , m p ) μ ( d ) ⌊ n p d ⌋ ⌊ m p d ⌋ \begin{aligned}\sum\limits_{p\in prime}\sum\limits_{i=1}^n\sum\limits_{j=1}^n[gcd(i,j)==p] &=\sum\limits_{p\in prime}\sum\limits_{i=1}^{\frac{n}{p}}\sum\limits_{j=1}^{\frac{n}{p}}[gcd(i,j)==1]\\ &=\sum\limits_{p\in prime}\sum\limits_{d=1}^{min(\frac{n}{p},\frac{m}{p})}\mu(d)\sum\limits_{i=1}^{\frac{n}{p}}\sum\limits_{j=1}^{\frac{n}{p}}[d|gcd(i,j)]\\ &=\sum\limits_{p\in prime}\sum\limits_{d=1}^{min(\frac{n}{p},\frac{m}{p})}\mu(d)\sum\limits_{i=1}^{\frac{n}{pd}}\sum\limits_{j=1}^{\frac{n}{pd}}1\\ &=\sum\limits_{p\in prime}\sum\limits_{d=1}^{min(\frac{n}{p},\frac{m}{p})}\mu(d){\left \lfloor \frac{n}{pd} \right \rfloor}{\left \lfloor \frac{m}{pd} \right \rfloor}\\ \\ \end{aligned} pprimei=1nj=1n[gcd(i,j)==p]=pprimei=1pnj=1pn[gcd(i,j)==1]=pprimed=1min(pn,pm)μ(d)i=1pnj=1pn[dgcd(i,j)]=pprimed=1min(pn,pm)μ(d)i=1pdnj=1pdn1=pprimed=1min(pn,pm)μ(d)pdnpdm
令 T = p d 令T=pd T=pd
∑ p ∈ p r i m e ∑ d = 1 m i n ( n p , m p ) μ ( d ) ⌊ n p d ⌋ ⌊ m p d ⌋ = ∑ T = 1 m i n ( n , m ) ⌊ n T ⌋ ⌊ m T ⌋ ∑ t ∣ T , t ∈ p r i m e μ ( T t ) \begin{aligned}\sum\limits_{p\in prime}\sum\limits_{d=1}^{min(\frac{n}{p},\frac{m}{p})}\mu(d){\left \lfloor \frac{n}{pd} \right \rfloor}{\left \lfloor \frac{m}{pd} \right \rfloor} &=\sum\limits_{T=1}^{min(n,m)}{\left \lfloor \frac{n}{T} \right \rfloor}{\left \lfloor \frac{m}{T} \right \rfloor}\sum\limits_{t|T,t\in prime}\mu(\frac{T}{t}) \\ \end{aligned} pprimed=1min(pn,pm)μ(d)pdnpdm=T=1min(n,m)TnTmtT,tprimeμ(tT)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e7+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int mu[N],mm[N],su[N],num;
bool vis[N];
void init()
{
    mu[1]=1;
    for(int i=2;i<N;++i){
        if(!vis[i])su[++num]=i,mu[i]=-1;
        for(int j=1;j<=num&&i*su[j]<N;++j){
            vis[i*su[j]]=1;
            if(i%su[j]==0)break;
            mu[i*su[j]]=-mu[i];
        }
    }
    for(int i=1;i<=num;++i)
        for(int j=1;su[i]*j<N;++j)mm[su[i]*j]+=mu[j];
    for(int i=1;i<N;++i)mm[i]+=mm[i-1];
}

LL outside(int n,int m)
{
    LL ans=0;
    for(int L=1,R;L<=n;L=R+1){
        R=min(n/(n/L),m/(m/L));
        ans+=(LL)(n/L)*(m/L)*(mm[R]-mm[L-1]);
    }
    return ans;
}
int main()
{
    init();
    int T,n,m;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        if(n>m)swap(n,m);
        printf("%lld\n",outside(n,m));
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值