51 NOD 1239 欧拉函数之和(杜教筛)

    xiaoxiao2021-03-26  5

    1239 欧拉函数之和 基准时间限制:3 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 收藏 关注 对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler’s totient function、φ函数、欧拉商数等。例如:φ(8) = 4(Phi(8) = 4),因为1,3,5,7均和8互质。 S(n) = Phi(1) + Phi(2) + …… Phi(n),给出n,求S(n),例如:n = 5,S(n) = 1 + 1 + 2 + 2 + 4 = 10,定义Phi(1) = 1。由于结果很大,输出Mod 1000000007的结果。 Input 输入一个数N。(2 <= N <= 10^10) Output 输出S(n) Mod 1000000007的结果。 Input示例 5 Output示例 10

    /* 杜教筛. 求积性函数前缀和. 欧拉函数因子的phi值之和等于n. 然后求法就和莫比乌斯函数那道题一样了。 注意取模中间有除法,求个逆元就好了。。 */ #include<iostream> #include<cstdio> #define MAXN 2000001 #define ha 1333333 #define mod 1000000007 #define LL unsigned long long #define ni 500000004 using namespace std; int phi[MAXN],p[MAXN],cut,pri[MAXN],tot,head[MAXN]; LL n,sum[MAXN]; struct data{int next;LL x,v;}e[MAXN]; bool vis[MAXN]; void add(int u,LL v,LL x) { e[++cut].v=v;e[cut].x=x;e[cut].next=head[u];head[u]=cut; } void pre() { phi[1]=1; for(int i=2;i<=MAXN-1;i++) { if(!vis[i]) vis[i]=true,pri[++tot]=i,phi[i]=i-1; for(int j=1;j<=tot&&i*pri[j]<=MAXN-1;j++) { if(!vis[i*pri[j]]) vis[i*pri[j]]=true; if(i%pri[j]) phi[i*pri[j]]=phi[i]*(pri[j]-1); else {phi[i*pri[j]]=phi[i]*pri[j];break ;} } } for(int i=1;i<=MAXN-1;i++) sum[i]=(sum[i-1]+phi[i])%mod; return ; } LL slove(LL x) { if(x<MAXN) return sum[x]; LL ans=0,k=x%ha,last; for(int i=head[k];i;i=e[i].next) if(e[i].v==x) return e[i].x; for(LL i=2;i<=x;i=last+1) { last=x/(x/i); ans=(ans+(last-i+1)%mod*slove(x/i)%mod)%mod; } ans=((x%mod*(x+1)%mod)%mod*ni%mod-ans+mod)%mod; add(k,x,ans); return ans; } int main() { pre(); cin>>n; cout<<slove(n); return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-600290.html

    最新回复(0)