【HDU 6428】Calculate 莫比乌斯反演+线性筛

本文详细介绍了使用素数筛法进行大规模数论问题求解的代码实现,通过构建素数表并利用其特性,高效计算特定数学函数的值。适用于处理涉及大量整数运算与素数判断的问题。

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

题解

1277930-20180823180542674-702921049.png

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1LL<<30;
const int N = 10000000;
int prime[N+5], low[N+5], check[N+5], pow_cnt[N+5], tot, f[N+5], f2[N+5], f3[N+5];
void sieve() {
    memset(check, 0, sizeof(check));
    low[1] = 1; tot = 0; f[1] = f2[1] = f3[1] = 1; pow_cnt[1] = 0; 
    for(int i = 2; i <= N; ++i) {
        if(!check[i]) {
            low[i] = i; prime[tot++] = i;f[i] = i-2;
            f2[i] = i; f3[i] = i; pow_cnt[i] = 1;
        }
        for(int j = 0; j < tot; ++j) {
            if(i * prime[j] > N) break;
            check[i*prime[j]] = 1;
            if(i % prime[j] == 0) {
                pow_cnt[i * prime[j]] = pow_cnt[i] + 1;
                low[i * prime[j]] = low[i] * prime[j];             
                if(low[i] == i) {
                    if(i == prime[j]) f[i * prime[j]] = prime[j]*prime[j]+1-2*prime[j];
                    else f[i * prime[j]] = f[i] * prime[j];
                    f2[i * prime[j]] = f2[i];
                    f3[i * prime[j]] = f3[i];
                    if(pow_cnt[i*prime[j]] % 2 == 1) f2[i * prime[j]] *= prime[j];
                    if(pow_cnt[i*prime[j]] % 3 == 1) f3[i * prime[j]] *= prime[j];
                }else {
                    f[i * prime[j]] = f[i / low[i]] * f[low[i] * prime[j]];
                    f2[i * prime[j]] = f2[i / low[i]] * f2[low[i] * prime[j]];
                    f3[i * prime[j]] = f3[i / low[i]] * f3[low[i] * prime[j]];
                }
                break;
            }else {
                low[i * prime[j]] = prime[j];
                pow_cnt[i * prime[j]] = 1;
                f[i * prime[j]] = f[i] * f[prime[j]];
                f2[i * prime[j]] = f2[i] * f2[prime[j]];
                f3[i * prime[j]] = f3[i] * f3[prime[j]];
            }
        }
    }
}
int t, A, B, C;
int main() {
    sieve();
    // for(int i = 1; i <= 100; ++i) {
    //     cout << f3[i] << " ";
    // }cout << endl;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d%d", &A, &B, &C);
        ll ans = 0;
        for(int i = 1; i <= max(A,max(B,C)); ++i) {
            ans = (ans + (A/i)*(B/f2[i])%mod*(C/f3[i])%mod*f[i]%mod)%mod;
        }
        cout << ans << endl;
    }
}

转载于:https://www.cnblogs.com/ogiso-setsuna/p/9525425.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值