[20191003 room test] Titan

太阳神拉很喜欢最小公倍数,有一天他想到了一个关于最小公倍数的题目
求满足如下条件的数对(a,b)对数:
a,b 均为正整数且 a,b<=n 而lcm(a,b)>n
其中的 lcm 当然表示最小公倍数
答案对 1,000,000,007取模

Data range is 1e10, playing table looking for a long useless ...... found law
would chant Mobius inversion

Topic Requirements:

\[\sum_{i=1}^{n}\sum_{j=1}^{n}[lcm(i,j)> n]\]

But more than too much, then we in turn request, and finally to reduce the total

We are seeking:

\[\sum_{i=1}^{n}\sum_{j=1}^{n}[lcm(i,j)\leq n]\]

First \ (lcm \) apart

\[\sum_{i=1}^{n}\sum_{j=1}^{n}[\dfrac{i·j}{gcd(i,j)}\leq n]\]

See \ (GCD \) , enumeration \ (i, j \) submultiple \ (D \)

\[\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{n}[\dfrac{i·j}{d}\leq n]\]

Pull out the inversion:

\[\sum_{d=1}^{n}\sum_{i'=1}^{\lfloor{\frac{n}{d}}\rfloor}\sum_{j'=1}^{\lfloor{\frac{n}{i'·d}}\rfloor}[gcd(i',j')=1]\]

Cited 入莫比乌斯 function:

\[\sum_{d=1}^{n}\sum_{i'=1}^{\lfloor{\frac{n}{d}}\rfloor}\sum_{j'=1}^{\lfloor{\frac{n}{i'·d}}\rfloor}\mu(gcd(i',j'))\]

Re-enumeration \ (i ', j' \ ) submultiple \ (D '\) , inversion continues

\[\sum_{d=1}^{n}\sum_{d'=1}^{\sqrt{\frac{n}{d}}}\mu(d')\sum_{i''=1}\sum_{j''=1}\lfloor{\frac{n}{d·d'^2i''}}\rfloor\]

The \ (d '\) out:

\ [\ Sum_ {d '= 1} ^ {\ sqrt {n}} \ mu (d') [d · i '' · j '' \ leq \ frac {n} {d '^ 2} \ text { the number of groups}] \]

Then is the desire to meet the \ (d · i '' · j '' \ leq \ frac {n} {d '^ 2} \) number of triplets (d, i' ', j ' ') of the

This can be \ (\ Theta (n ^ { \ frac {2} {3}}) \) calculated

On it

Code:

#include<bits/stdc++.h>
#define ll long long
#define N 100005
#define M 100000
#define mod 1000000007
using namespace std;

ll n,ans,siz,sum,maxn,x;
ll mu[N],prime[N],primenum;
bool isprime[N];

template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

void init()
{
    mu[1]=1;
    for(register int i=2;i<=M;++i)
    {
        if(!isprime[i])
        {
            prime[++primenum]=i;
            mu[i]=-1;
        }
        for(register int j=1;j<=primenum;++j)
        {
            if(i*prime[j]>M) break;
            isprime[i*prime[j]]=1;
            if(!(i%prime[j]))
            {
                mu[i*prime[j]]=0;
                break;
            }
            mu[i*prime[j]]=-mu[i];
        }
    }
}

int main()
{
    freopen("ra.in","r",stdin);
    freopen("ra.out","w",stdout);
    read(n);
    init();
    siz=(ll)(sqrt(n)+0.5);
    for(register ll i=1;i<=siz;++i)
    {
        sum=0;
        maxn=n/i/i;
        for(register ll j=1;j*j*j<=maxn;++j)
        { 
            for(register ll k=j;k*k<=maxn/j;++k)
            {
                x=(maxn/j/k-k+1);
                if(j==k) sum=(sum+1+(x-1)*3)%mod;
                else sum=(sum+3+(x-1)*6)%mod;
            }
        }
        sum%=mod;
        ans=(ans+mu[i]*sum)%mod;
    }
    ans=((n%mod)*(n%mod)-ans)%mod;
    while(ans<0) ans+=mod;
    printf("%lld\n",ans);
    return 0;
}
/*
10000000000
210705255
*/

Guess you like

Origin www.cnblogs.com/tqr06/p/11619827.html