【GDOI2018模拟8.11】质数

本文探讨了一种计算特定数学序列的方法,该序列涉及质因子的数量及其在杜教筛算法中的应用。通过将问题转化为求解积性函数,利用杜教筛优化计算过程,并介绍了一种新的求和技巧来解决大规模数据范围内的问题。

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

Description

i=1n2f(i)

f(i)表示i的不同的质因子个数
n<=10^12

Solution

我们设g(i)=2^f(i),显然g是积性函数
那么我们可以尝试杜教筛g
把g卷上一个mu,设g*mu=h
显然h也是积性函数
分析一下h(p^k),我们可以发现h(p^k)=[k==1]
特别的h[1]=1
那么归纳一下我们可以发现h=mu^2!!
也就是g*mu=mu^2
两边再卷上一个I,那么g=mu^2*I
说人话就是g(n)=d|nmu(i)2
这样是可以杜教筛的,但是由于出题人很不良心这样会被卡成暴力分
我们需要一个更优秀的解法
先把原式子写出来

Ans=i=1nd|iμ(d)2

枚举j=i/d,
Ans=j=1nd=1nj2μ(d)2

考虑ni=1μ(d)2要怎么求
如果存在一个p^2|d那么mu(d)^2=0否则mu(d)^2=1
如果我们考虑容斥,枚举一个p^2把答案减去n/(p^2)
但这样会算重所有我们要加上n/(p*p’)^2
可以发现容斥系数相当于mu
所以
i=1nμ(d)2=i=1nμ(i)ni2

Ans=j=1nd=1nj2μ(d)nd2j
Ans=d=1nμ(d)j=1nd2nd2j

后面可以分块,复杂度O(nlogn13)

Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int N=1e6+5,mo=998244353;
int p[N],mu[N];
bool bz[N];
ll n,ans;
void prepare(int n) {
    mu[1]=1;
    fo(i,2,n) {
        if (!bz[i]) p[++p[0]]=i,mu[i]=-1;
        fo(j,1,p[0]) {
            int k=i*p[j];if (k>n) break;
            bz[k]=1;if (!(i%p[j])) break;
            mu[k]=-mu[i];
        }
    }
}
int main() {
    scanf("%lld",&n);
    int m=sqrt(n);
    prepare(m);
    fo(i,1,m) {
        if (!mu[i]) continue;
        int sum=0;ll nn=n/i/i;
        for(ll l=1,r;l<=nn;l=r+1) {
            r=nn/(nn/l);
            (sum+=(ll)(r-l+1)*(nn/l)%mo)%=mo;
        }
        if (mu[i]==1) (ans+=sum)%=mo;
        else (ans+=mo-sum)%=mo;
    }
    printf("%d\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值