洛谷 P3911 最小公倍数之和

最小公倍数之和

Here

仅作笔记和理解

题意

对于 A 1 , A 2 , ⋅ ⋅ ⋅ , A N A_{1},A_{2},···,A_{N} A1,A2,,AN ∑ i = 1 N ∑ j = 1 N l c m ( A i , A j ) \sum\limits_{i=1}^{N}\sum\limits_{j=1}^{N}lcm(A_{i},A_{j}) i=1Nj=1Nlcm(Ai,Aj)的值
数据范围: 1 ≤ N ≤ 50000 , 1 ≤ A i ≤ 50000 1\leq N\leq 50000,1\leq A_{i}\leq 50000 1N50000,1Ai50000

乍一看好像搞不了,实际上又搞得了

这道题是让我们求任意两个数的 l c m lcm lcm的值

转换思路,我们不枚举下标,我们枚举每一个值,统计每种值的数的出现次数

莫比乌斯反演,开始化式子= =

n = 50000 n=50000 n=50000

∑ i = 1 n ∑ j = 1 n i ⋅ j ⋅ C i ⋅ C j g c d ( i , j ) \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\frac{i·j·C_{i}·C_{j}}{gcd(i,j)} i=1nj=1ngcd(i,j)ijCiCj

开始套路枚举 g c d gcd gcd

∑ g = 1 n ∑ i = 1 n g ∑ j = 1 n g i ⋅ g ⋅ j ⋅ g ⋅ C i ⋅ C j g [ g c d ( i , j ) = 1 ] \sum\limits_{g=1}^{n}\sum\limits_{i=1}^{\frac{n}{g}}\sum\limits_{j=1}^{\frac{n}{g}}\frac{i·g·j·g·C_{i}·C_{j}}{g}[gcd(i,j)=1] g=1ni=1gnj=1gngigjgCiCj[gcd(i,j)=1]

套路替换莫比乌斯函数

∑ g = 1 n ∑ i = 1 n g ∑ j = 1 n g i ⋅ j ⋅ g ⋅ C i g ⋅ C j g ⋅ ∑ x ∣ g c d ( i , j ) μ ( x ) \sum\limits_{g=1}^{n}\sum\limits_{i=1}^{\frac{n}{g}}\sum\limits_{j=1}^{\frac{n}{g}}{i·j·g·C_{ig}·C_{jg}}·\sum\limits_{x|gcd(i,j)}μ(x) g=1ni=1gnj=1gnijgCigCjgxgcd(i,j)μ(x)

套路枚举 x x x的值

∑ g = 1 n ∑ x = 1 n g ∑ i = 1 n x g ∑ j = 1 n x g i ⋅ x ⋅ j ⋅ x ⋅ g ⋅ C i x g ⋅ C j x g ⋅ μ ( x ) \sum\limits_{g=1}^{n}\sum\limits_{x=1}^{\frac{n}{g}}\sum\limits_{i=1}^{\frac{n}{xg}}\sum\limits_{j=1}^{\frac{n}{xg}}{i·x·j·x·g·C_{ixg}·C_{jxg}}·μ(x) g=1nx=1gni=1xgnj=1xgnixjxgCixgCjxgμ(x)

变换一下 x x x

∑ g = 1 n ∑ g ∣ x n ∑ i = 1 n x ∑ j = 1 n x i ⋅ x 2 g ⋅ j ⋅ C i x ⋅ C j x ⋅ μ ( x g ) \sum\limits_{g=1}^{n}\sum\limits_{g|x}^{n}\sum\limits_{i=1}^{\frac{n}{x}}\sum\limits_{j=1}^{\frac{n}{x}}{i·\frac{x^{2}}{g}·j·C_{ix}·C_{jx}}·μ(\frac{x}{g}) g=1ngxni=1xnj=1xnigx2jCixCjxμ(gx)

演他一手就得到了

∑ x = 1 n ∑ g ∣ x ∑ i = 1 n x ∑ j = 1 n x i ⋅ x 2 g ⋅ j ⋅ C i x ⋅ C j x ⋅ μ ( x g ) \sum\limits_{x=1}^{n}\sum\limits_{g|x}\sum\limits_{i=1}^{\frac{n}{x}}\sum\limits_{j=1}^{\frac{n}{x}}{i·\frac{x^{2}}{g}·j·C_{ix}·C_{jx}}·μ(\frac{x}{g}) x=1ngxi=1xnj=1xnigx2jCixCjxμ(gx)

整理一下就变成了

∑ x = 1 n ∑ g ∣ x x 2 g ⋅ μ ( x g ) ∑ i = 1 n x i ⋅ C i x ∑ j = 1 n x j ⋅ C j x \sum\limits_{x=1}^{n}\sum\limits_{g|x}\frac{x^{2}}{g}·μ(\frac{x}{g})\sum\limits_{i=1}^{\frac{n}{x}}i·C_{ix}\sum\limits_{j=1}^{\frac{n}{x}}j·C_{jx} x=1ngxgx2μ(gx)i=1xniCixj=1xnjCjx

=> ∑ x = 1 n ∑ g ∣ x x 2 g ⋅ μ ( x g ) ( ∑ i = 1 n x i ⋅ C i x ) 2 \sum\limits_{x=1}^{n}\sum\limits_{g|x}\frac{x^{2}}{g}·μ(\frac{x}{g})(\sum\limits_{i=1}^{\frac{n}{x}}i·C_{ix})^{2} x=1ngxgx2μ(gx)(i=1xniCix)2

所以接下来就可以预处理 ∑ g ∣ x x 2 g ⋅ μ ( x g ) \sum\limits_{g|x}\frac{x^{2}}{g}·μ(\frac{x}{g}) gxgx2μ(gx),然后枚举 x x x的值, O ( n l o g n ) O(nlogn) O(nlogn)就可以算出式子的值了。

其实也可以预处理 ( ∑ i = 1 n x i ⋅ C i x ) 2 (\sum\limits_{i=1}^{\frac{n}{x}}i·C_{ix})^{2} (i=1xniCix)2,然后枚举x的值

其实也可以两个都预处理(但没必要

Code 预处理 ( ∑ i = 1 n x i ⋅ C i x ) 2 (\sum\limits_{i=1}^{\frac{n}{x}}i·C_{ix})^{2} (i=1xniCix)2

/****************************
* Author : 水娃             *
* Date : 2020-08-07-18.38.19*
****************************/
#pragma GCC optimize(3,"Ofast","inline")
#include
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
#define ll long long
#define debug(a) cout<<#a<<" is "<
#define ull unsigned long long
#define fi first
#define se second
typedef pair<int,int>pii;
typedef pair<ll,int>pli;
typedef pair<int,ll>pil;
typedef pair<ll,ll>pll;
const ll mo=(ll)1e9+7;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
const ll MAXN=5e4+100;
int cnt;
ll p[MAXN],mu[MAXN],vis[MAXN];
void init()
{
    ll num;
    mu[1]=1;
    for(ll i=2;i<MAXN;++i)
    {
        if(!vis[i])
        {
            mu[i]=-1;
            p[++cnt]=i;
        }
        for(int j=1;j<=cnt&&(num=i*p[j])<MAXN;++j)
        {
            vis[num]=1;
            if(i%p[j]==0)break;
            mu[num]=-mu[i];
        }
    }
}
int n;
ll a[51000],tot[51000],sum[51000];
void work()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        tot[a[i]]++;
    }
    for(ll x=1;x<=50000;x++)
    {
        ll top=50000/x;
        ll tmp=0;
        for(ll i=1;i<=top;i++)
        {
            tmp=tmp+i*tot[i*x];;
        }
        sum[x]=tmp*tmp;
    }
    ll ans=0;
    for(ll g=1;g<=50000;g++)
    {
        ll top=50000/g;
        ll tmp=0;
        for(ll j=1;j<=top;j++)
        {
            tmp=tmp+j*g*j*mu[j]*sum[g*j];
        }
        ans=ans+tmp;
    }
    cout<<ans<<"\n";
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    init();
    ///int T;cin>>T;while(T--)
        work();
    return 0;
}

Code 预处理 ∑ g ∣ x x 2 g ⋅ μ ( x g ) \sum\limits_{g|x}\frac{x^{2}}{g}·μ(\frac{x}{g}) gxgx2μ(gx)

/****************************
* Author : 水娃             *
* Date : 2020-08-07-18.38.19*
****************************/
#pragma GCC optimize(3,"Ofast","inline")
#include
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
#define ll long long
#define debug(a) cout<<#a<<" is "<
#define ull unsigned long long
#define fi first
#define se second
typedef pair<int,int>pii;
typedef pair<ll,int>pli;
typedef pair<int,ll>pil;
typedef pair<ll,ll>pll;
const ll mo=(ll)1e9+7;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
const ll MAXN=5e4+100;
int cnt;
ll p[MAXN],mu[MAXN],vis[MAXN];
void init()
{
    ll num;
    mu[1]=1;
    for(ll i=2;i<MAXN;++i)
    {
        if(!vis[i])
        {
            mu[i]=-1;
            p[++cnt]=i;
        }
        for(int j=1;j<=cnt&&(num=i*p[j])<MAXN;++j)
        {
            vis[num]=1;
            if(i%p[j]==0)break;
            mu[num]=-mu[i];
        }
    }
}
int n;
ll a[51000],tot[51000],sum[51000];
void work()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        tot[a[i]]++;
    }
    int num;
    for(int i=1;i<=50000;i++)
    {
        for(int j=1;(num=i*j)<=50000;j++)
        {
            sum[num]+=i*mu[j]*j*j;
        }
    }
    ll ans=0;
    for(int i=1;i<=50000;i++)
    {
        int top=50000/i;
        ll tmp=0;
        for(int j=1;j<=top;j++)
        {
            tmp=tmp+j*tot[i*j];
        }
        ans=ans+sum[i]*tmp*tmp;
    }
    cout<<ans<<"\n";
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    init();
    ///int T;cin>>T;while(T--)
        work();
    return 0;
}

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