首页 > 代码库 > 51Nod 1239 欧拉函数之和

51Nod 1239 欧拉函数之和

Description

求\(\sum_{i=1}^n\varphi(i),n\leqslant 10^{10}\)

Solution

杜教筛...贴代码...

Code

#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef long double ld;const int N = 2000050;const ll p = 1000000007;ll Pow(ll a,ll b,ll r=1) { for(;b;b>>=1,a=a*a%p) if(b&1) r=r*a%p;return r; }ll mul(ll a,ll b) { return (a*b-((ll)((ld)a/p*b+1e-3))*p+p)%p; }int b[N],pr[N],cp;ll phi[N],sp[N],inv2=Pow(2,p-2);void pre(int n) {	for(int i=2;i<=n;i++) {		if(!b[i]) pr[++cp]=i,phi[i]=i-1;		for(int j=1;j<=cp && i*pr[j]<=n;j++) {			b[i*pr[j]]=1;			if(i%pr[j]) phi[i*pr[j]]=phi[i]*(pr[j]-1);			else { phi[i*pr[j]]=phi[i]*pr[j];break; }		}	}phi[1]=1;	for(int i=1;i<=n;i++) sp[i]=(sp[i-1]+phi[i])%p;}map<ll,ll> mp;ll S(ll n) {	if(n<=2000000) return sp[n];	if(mp.count(n)) return mp[n];	ll fn=(n%p)*((n+1)%p)%p*inv2%p;	for(ll i=2,j;i<=n;i=j+1) {		j=n/(n/i);		fn=(fn-(j-i+1)%p*S(n/i)%p+p)%p;	}return mp[n]=fn;}int main() {	pre(2000000);	ll n;	scanf("%lld",&n);	printf("%lld\n",S(n));	return 0;}

  

51Nod 1239 欧拉函数之和