【51NOD 1239】欧拉函数之和

来源:互联网 发布:禁止安装任何软件方法 编辑:程序博客网 时间:2024/05/21 19:26

Description


i=1nφ(i)

Solution

一道杜教筛裸题
有结论:(证明在这里)

d|nφ(d)=n

则:

d=1ni|dφ(i)=(1+n)n2

i=1nj=1niφ(j)=(1+n)n2

i=1nφ(i)=(1+n)n2i=2nj=1niφ(j)

直接上杜教筛加上哈希即可,

复杂度:O(n23)

Code

#include <cstdio>#include <cstdlib>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;typedef long long LL;const int N=5000500,M=1544657,mo=1e9+7;const LL eni=500000004;int n;bool prz[N];int pr[N];int phi[N];int Hx[M+1][2];int co;int HX(LL q){    int i=q%M;    while(Hx[i][0]&&Hx[i][0]!=q)i=(i+1)%M;    return i;}LL Gphi(LL q){    if(q<=n)return phi[q];    int t=HX(q);    if(Hx[t][0])return Hx[t][1];    Hx[t][0]=q;    LL ans=0,i=2;    while(i<=q)    {        LL ni=q/(q/i);        ans=(ans+(ni-i+1)*Gphi(q/i))%mo;        i=ni+1;    }    q%=mo;    return Hx[t][1]=(q*(q+1)%mo*eni%mo-ans)%mo;}int main(){    n=N-10;    phi[1]=1;    fo(i,2,n)    {        if(!prz[i])pr[++pr[0]]=i,phi[i]=i-1;        fo(j,1,pr[0])        {            LL t=pr[j]*i;            if(t>n)break;            prz[t]=1;            phi[t]=phi[i]*pr[j];            if(i%pr[j]==0)break;            phi[t]=phi[i]*(pr[j]-1);        }    }    fo(i,2,n)phi[i]=(phi[i]+phi[i-1])%mo;    LL q;    scanf("%lld",&q);    printf("%lld\n",(Gphi(q)+mo)%mo);    return 0;}
0 0
原创粉丝点击