求a[gcd(i,j)]之和

本文探讨了一个关于数论的问题,具体来说是如何计算特定数组中所有元素的组合的数学期望值,利用了莫比乌斯函数和数论知识来简化计算过程,并提供了一段C++实现代码。

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

给定长度为 NN 的数组 a ,求

1in,1jma[gcd(i,j)]∑1≤i≤n,1≤j≤ma[gcd(i,j)]

数据范围: 1n,mN1051≤n,m≤N≤105

f(n,m)=i=1nj=1ma[gcd(i,j)]=d=1min(n,m)i=1nj=1ma[d]×[gcd(i,j)==d]=d=1min(n,m)a[d]×i=1ndj=1md[gcd(i,j)==1]f(n,m)=∑i=1n∑j=1ma[gcd(i,j)]=∑d=1min(n,m)∑i=1n∑j=1ma[d]×[gcd(i,j)==d]=∑d=1min(n,m)a[d]×∑i=1nd∑j=1md[gcd(i,j)==1]

先知道莫比乌斯函数的定义:
d|nμ(d)=1 n=1d|nμ(d)=0 n>1∑d|nμ(d)=1 (当n=1)∑d|nμ(d)=0 (当n>1)


g(n,m)=i=1nj=1m[gcd(i,j)==1]=i=1nj=1md|gcd(i,j)μ(d)=d=1min(n,m)μ(d)×nd×mdg(n,m)=∑i=1n∑j=1m[gcd(i,j)==1]=∑i=1n∑j=1m∑d|gcd(i,j)μ(d)=∑d=1min(n,m)μ(d)×nd×md


f(n,m)=d=1min(n,m)a[d]×g(nd,md)f(n,m)=∑d=1min(n,m)a[d]×g(nd,md)

复杂度计算:ni=1niO(nlogn)∑i=1nni≈O(nlogn)

美团的笔试题给定了A数组,即a1=p,ai=(ai+153)%pa1=p,ai=(ai+153)%p
代码如下:

#include <bits/stdc++.h>
using namespace std;
int a[100007],mu[100007];
using ll = long long;
ll g(int n, int m)
{
    ll ret = 0;
    for(int i=1; i<=min(n, m); ++i)
        ret+=(ll)mu[i]*(n/i)*(m/i);
    return ret;
}
int main()
{
    int N,n,m,p;
    scanf("%d%d%d%d",&N,&n,&m,&p);
    ll ans = 0;
    mu[1]=1;
    for(int i=1; i<=N; ++i)
        for(int j=2*i;j<=N;j+=i)
            mu[j]-=mu[i];
    a[1]=p;
    for(int i=2; i<=N; ++i)
        a[i]=(a[i-1]+153)%p;
    for(int i=1; i<=min(n, m); ++i)
    {
        ans+=(ll)a[i]*g(n/i,m/i);
    }
    cout << ans << '\n';
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值