[JZOJ5250]【GDOI2018模拟8.11】质数

Description

i=1n2f(i) ,其中f(i)表示i的不同质因子个数

Solution

显然,2^f(i)就是每个质因子选或者不选

那么2^f(i)等价于 d|i[gcd(d,i/d)=1] ,两个互质一定不会有相同的

c(q)=d|i[gcd(d,i/d)=q]
反演一下
易得 c(1)=j=1iμ(j)g(j) ,其中 g(j)=j|pc(p)
因为 gcd(d,i/d)=q ,d和i/d都含有q这个因子,那么一定 q2|i

所以 c(1)=j2|iμ(j)g(j)

因为 g(j)=j|pc(p) ,并且 j2|i
设h(i)为i的约数个数和

那么 c(1)=j2|iμ(j)h(ij2)
总的就是 i=1nj2|iμ(j)h(ij2)

交换主体,把 μ 提出来
j=1nμ(j)i=1nj2h(i)

1到N的约数个数和,不妨枚举i作为约数的贡献,即i在N内倍数个数显然是 ni

原式化为 j=1nμ(j)i=1nj2nj2i

前面分块,后面也分块处理
复杂度 i=1nni=nlnn ,非常优秀

Code

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define N 1000005
#define LL long long
#define mo 998244353
using namespace std;
LL n,mu[N],n1,s[N];
int pr[N],l;
bool bz[N];
void prp()
{
    mu[1]=s[1]=1;
    fo(i,2,n1)
    {
        if(!bz[i])
        {
            mu[i]=-1;
            pr[++l]=i;
        }
        for(int j=1;j<=l&&pr[j]*i<=n1;j++)
        {
            bz[i*pr[j]]=1;
            if(i%pr[j]==0)
            {
                mu[i*pr[j]]=0;
                break;
            }
            else mu[i*pr[j]]=-mu[i];
        }
        s[i]=(s[i-1]+mu[i])%mo;
    }
}
int main()
{
    cin>>n;
    n1=sqrt(n);
    prp();
    LL i=1,ans=0;
    while(i<=n1)
    {
        LL s1=0,m=n/(i*i),i1=sqrt(n/m),p=1;
        while(p<=m)
        {
            LL p1=m/(m/p);
            s1=(s1+(m/p)*(p1-p+1)%mo)%mo;
            p=p1+1;
        }
        ans=(ans+(s[i1]-s[i-1]+mo)%mo*s1)%mo;
        i=i1+1;
    }
    printf("%lld\n",ans);
}   
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值