[JZOJ5250]【GDOI2018模拟8.11】质数

来源:互联网 发布:八爪鱼支架 知乎 编辑:程序博客网 时间:2024/06/06 05:03

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 998244353using 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);}   
原创粉丝点击