P1390 公约数的和(莫比乌斯反演)

题目链接

题意:

给定 n n n,求 ∑ i = 1 n ∑ j = i + 1 n g c d ( i , j ) \sum_{i=1}^{n}\sum_{j=i+1}^{n}gcd(i,j) i=1nj=i+1ngcd(i,j) ( n < = 2 e 6 ) (n<=2e6) (n<=2e6)

推导:

第一步,按套路先把 g c d gcd gcd提到前面来,

∑ g = 1 n g ∑ i = 1 n ∑ j = i + 1 n [ g = g c d ( i , j ) ] \sum_{g=1}^{n}g\sum_{i=1}^{n}\sum_{j=i+1}^{n}[g=gcd(i,j)] g=1ngi=1nj=i+1n[g=gcd(i,j)]

第二步,我们令 f ( g ) = ∑ i = 1 n ∑ j = i + 1 n [ g = g c d ( i , j ) ] f(g)=\sum_{i=1}^{n}\sum_{j=i+1}^{n}[g=gcd(i,j)] f(g)=i=1nj=i+1n[g=gcd(i,j)],此时我们要求的东西就是 ∑ g = 1 n g f ( g ) \sum_{g=1}^{n}gf(g) g=1ngf(g),先放着。

然后这时候我们在莫比乌斯反演的公式中二选一,有经验之后就知道该选哪个了。
我们令,

F ( g ) = ∑ g ∣ d f ( d ) F(g)=\sum_{g|d}f(d) F(g)=gdf(d)

                 = ∑ g ∣ d ∑ i = 1 n ∑ j = i + 1 n [ d = g c d ( i , j ) ] \;\;\;\;\;\;\;\;=\sum_{g|d}\sum_{i=1}^{n}\sum_{j=i+1}^{n}[d=gcd(i,j)] =gdi=1nj=i+1n[d=gcd(i,j)]

                 = ∑ i = 1 n ∑ j = i + 1 n [ g ∣ g c d ( i , j ) ] \;\;\;\;\;\;\;\;=\sum_{i=1}^{n}\sum_{j=i+1}^{n}[g|gcd(i,j)] =i=1nj=i+1n[ggcd(i,j)]

                 = ∑ i = 1 n ∑ j = i + 1 n [ g ∣ i ∧ g ∣ j ] \;\;\;\;\;\;\;\;=\sum_{i=1}^{n}\sum_{j=i+1}^{n}[g|i\wedge g|j] =i=1nj=i+1n[gigj]

                 = 1 2 ( ⌊ n g ⌋ ⌊ n g ⌋ − ⌊ n g ⌋ ) \;\;\;\;\;\;\;\;=\frac{1}{2} (\lfloor \frac{n}{g} \rfloor \lfloor \frac{n}{g} \rfloor -\lfloor \frac{n}{g} \rfloor) =21(gngngn)

根据反演公式,有 f ( g ) = ∑ g ∣ d μ ( d g ) F ( d ) f(g)=\sum_{g|d}\mu(\frac{d}{g})F(d) f(g)=gdμ(gd)F(d)

所以我们最后代回原来要求的式子中,

∑ g = 1 n g f ( g ) = ∑ g n ∑ g ∣ d μ ( d g ) F ( d ) \sum_{g=1}^{n}gf(g)=\sum_{g}^{n}\sum_{g|d}\mu(\frac{d}{g})F(d) g=1ngf(g)=gngdμ(gd)F(d)

前面推过了, F ( d ) F(d) F(d)可以 o ( 1 ) o(1) o(1)算,莫比乌斯函数可以预处理,所以最后的式子就可以 o ( n l o g n ) o(nlogn) o(nlogn)求出来了。

代码:

#include
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
typedef pair<int,int> P;
const ll MAXN=2000000;

ll prime[MAXN+10],notPrime[MAXN+10],mu[MAXN+10],tot;
void initMu(ll n)
{
    notPrime[1]=mu[1]=1;
    for(ll i=2;i<=n;i++)
    {
        if(!notPrime[i])prime[tot++]=i,mu[i]=-1;
        for(ll j=0;j<tot&&i*prime[j]<=n;j++)
        {
            notPrime[i*prime[j]]=1;
            if(i%prime[j])mu[i*prime[j]]=-mu[i];
            else {mu[i*prime[j]]=0;break;}
        }
    }
}

ll n;
ll getF(ll g)
{
    ll t=n/g;
    return (t*t-t)/2;
}

int main()
{
    initMu(MAXN);
    scanf("%lld",&n);
    ll ans=0;
    for(ll g=1;g<=n;g++)
    {
        for(ll d=g;d<=n;d+=g)
        {
            ans=ans+g*mu[d/g]*getF(d);
        }
    }
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(莫比乌斯反演)