[hdu6428]Calculate(数论 欧拉函数 莫比乌斯反演)

本文探讨了一个复杂的数学问题,即求解三重求和公式。通过将Euler totient函数和最大公约数概念分离,引入了辅助函数f(d)和g(d),并利用积性函数的性质和狄利克雷卷积进行优化。文章详细解释了如何使用线性筛算法高效计算这些函数,并附上了完整的C++代码实现。

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

题意

A,B,C1e7A,B,C≤1e7

i=1Aj=1Bk=1Cϕ(gcd(i,j2,k3))∑i=1A∑j=1B∑k=1Cϕ(gcd(i,j2,k3))

题解

很难受 写这题的时候真是又困又难受,冷静下来细想并没有那么难qwq
学计算机果然要身体好才行呀

对于这个东西,我们先想到把 phiphigcdgcd 拆开。
f(d)f(d) 表示存在多少个 i,j,ki,j,k 使得 d|gcd(i,j2,k3)d|gcd(i,j2,k3)
g(d)g(d) 表示存在多少个 i,j,ki,j,k 使得 d==gcd(i,j2,k3)d==gcd(i,j2,k3)
我们先不考虑怎么求 f,gf,g

那么 ans=g(d)ϕ(d)ans=∑g(d)∗ϕ(d)

容易发现

f(d)=d|kg(k)f(d)=∑d|kg(k)

然后我们莫比乌斯一下
g(d)=d|kμ(k/d)f(k)g(d)=∑d|kμ(k/d)∗f(k)

再把这个带入 ansans

ans=ϕ(d)d|kf(k)μ(k/d)ans=∑ϕ(d)∗∑d|kf(k)∗μ(k/d)

=kf(k)d|kϕ(d)μ(k/d)=∑kf(k)∑d|kϕ(d)∗μ(k/d)

两个积性函数的狄利克雷卷积还是积性函数,后面这部分可以搞一搞线筛出来。
前面这一部分也好算f(k)=AkBb[k]Cc[k]f(k)=Ak∗Bb[k]∗Cc[k]
b[k]为最小的x使得 xx%k==0x∗x%k==0
c[k]同理
然后b[k],c[k]也是积性函数,线筛搞搞就可以了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const int maxn = 1e7 + 10;
const int mod = 1<<30;
int prm[maxn], phi[maxn], tot; 
bool ok[maxn];

ui bb[maxn], cc[maxn], sx[maxn], fck[maxn];
void get_prime(int n){ 
tot = 0;
    memset(ok, 0, sizeof(ok)); phi[1] = 1;
    cc[1] = bb[1] = 1;
    sx[1] = 1;
    for (int i = 2; i <= n; i ++){
        if (!ok[i]){
            prm[++ tot] = i;
            phi[i] = i - 1;
            cc[i] = bb[i] = i;
            sx[i] = i - 2;
            fck[i] = i;
        }
        for (int j = 1; j <= tot; j ++){
            if (1LL * i * prm[j] > n) break;
            if (1LL * bb[i] * bb[i] % (i * prm[j]) == 0)
                bb[i * prm[j]] = bb[i];
            else bb[i * prm[j]] = bb[i] * prm[j];

            if (1LL * cc[i] * cc[i] % (i * prm[j]) * cc[i] % (i * prm[j]) == 0)
                cc[i * prm[j]] = cc[i];
            else cc[i * prm[j]] = cc[i] * prm[j];

            ok[i * prm[j]] = true;
            if (i % prm[j]){
                phi[i * prm[j]] = phi[i] * phi[prm[j]];
                sx[i * prm[j]] = sx[i] * sx[prm[j]];
                fck[i * prm[j]] = prm[j];
            }
            else{
                phi[i * prm[j]] = phi[i] * prm[j];
                sx[i * prm[j]] = sx[i / fck[i]] * (phi[fck[i] * prm[j]] - phi[fck[i]]);
                fck[i * prm[j]] = fck[i] * prm[j];          
                break;
            }
        }
    }
}

bool nsp[maxn];
void prepare(){
    get_prime(maxn - 1);
}
void work(){
    ui A,B,C;
    scanf("%u%u%u", &A, &B, &C);

    ui qwq = 0;
    for (int i = A; i; i --){
        qwq = qwq + 1LL * (A / i) * (B / bb[i]) * (C / cc[i]) * sx[i];
    }

    printf("%u\n", qwq % mod);
}
int main(){
    prepare();
    int T; scanf("%d", &T);
    while (T --)
        work();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值